Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: trivial white space
[CIFS] checkpatch cleanup
cifs: add cifs_revalidate_file
cifs: add a CIFSSMBUnixQFileInfo function
cifs: add a CIFSSMBQFileInfo function
cifs: overhaul cifs_revalidate and rename to cifs_revalidate_dentry

+334 -122
+2 -1
fs/cifs/cifsfs.c
··· 312 312 cifs_inode->clientCanCacheRead = false; 313 313 cifs_inode->clientCanCacheAll = false; 314 314 cifs_inode->delete_pending = false; 315 + cifs_inode->invalid_mapping = false; 315 316 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 316 317 cifs_inode->server_eof = 0; 317 318 ··· 639 638 setting the revalidate time to zero */ 640 639 CIFS_I(file->f_path.dentry->d_inode)->time = 0; 641 640 642 - retval = cifs_revalidate(file->f_path.dentry); 641 + retval = cifs_revalidate_file(file); 643 642 if (retval < 0) 644 643 return (loff_t)retval; 645 644 }
+2 -1
fs/cifs/cifsfs.h
··· 61 61 extern int cifs_rmdir(struct inode *, struct dentry *); 62 62 extern int cifs_rename(struct inode *, struct dentry *, struct inode *, 63 63 struct dentry *); 64 - extern int cifs_revalidate(struct dentry *); 64 + extern int cifs_revalidate_file(struct file *filp); 65 + extern int cifs_revalidate_dentry(struct dentry *); 65 66 extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); 66 67 extern int cifs_setattr(struct dentry *, struct iattr *); 67 68
+1
fs/cifs/cifsglob.h
··· 389 389 bool clientCanCacheRead:1; /* read oplock */ 390 390 bool clientCanCacheAll:1; /* read and writebehind oplock */ 391 391 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 392 + bool invalid_mapping:1; /* pagecache is invalid */ 392 393 u64 server_eof; /* current file size on server */ 393 394 u64 uniqueid; /* server inode number */ 394 395 struct inode vfs_inode;
+6
fs/cifs/cifsproto.h
··· 104 104 extern struct inode *cifs_iget(struct super_block *sb, 105 105 struct cifs_fattr *fattr); 106 106 107 + extern int cifs_get_file_info(struct file *filp); 107 108 extern int cifs_get_inode_info(struct inode **pinode, 108 109 const unsigned char *search_path, 109 110 FILE_ALL_INFO *pfile_info, 110 111 struct super_block *sb, int xid, const __u16 *pfid); 112 + extern int cifs_get_file_info_unix(struct file *filp); 111 113 extern int cifs_get_inode_info_unix(struct inode **pinode, 112 114 const unsigned char *search_path, 113 115 struct super_block *sb, int xid); ··· 144 142 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 145 143 const __u16 search_handle); 146 144 145 + extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 146 + u16 netfid, FILE_ALL_INFO *pFindData); 147 147 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 148 148 const unsigned char *searchName, 149 149 FILE_ALL_INFO *findData, ··· 156 152 FILE_ALL_INFO *findData, 157 153 const struct nls_table *nls_codepage, int remap); 158 154 155 + extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 156 + u16 netfid, FILE_UNIX_BASIC_INFO *pFindData); 159 157 extern int CIFSSMBUnixQPathInfo(const int xid, 160 158 struct cifsTconInfo *tcon, 161 159 const unsigned char *searchName,
+134 -1
fs/cifs/cifssmb.c
··· 500 500 } else if (pSMBr->hdr.WordCount == 13) { 501 501 cERROR(1, ("mount failed, cifs module not built " 502 502 "with CIFS_WEAK_PW_HASH support")); 503 - rc = -EOPNOTSUPP; 503 + rc = -EOPNOTSUPP; 504 504 #endif /* WEAK_PW_HASH */ 505 505 goto neg_err_exit; 506 506 } else if (pSMBr->hdr.WordCount != 17) { ··· 3230 3230 return rc; 3231 3231 } 3232 3232 3233 + int 3234 + CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 3235 + u16 netfid, FILE_ALL_INFO *pFindData) 3236 + { 3237 + struct smb_t2_qfi_req *pSMB = NULL; 3238 + struct smb_t2_qfi_rsp *pSMBr = NULL; 3239 + int rc = 0; 3240 + int bytes_returned; 3241 + __u16 params, byte_count; 3233 3242 3243 + QFileInfoRetry: 3244 + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3245 + (void **) &pSMBr); 3246 + if (rc) 3247 + return rc; 3234 3248 3249 + params = 2 /* level */ + 2 /* fid */; 3250 + pSMB->t2.TotalDataCount = 0; 3251 + pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3252 + /* BB find exact max data count below from sess structure BB */ 3253 + pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3254 + pSMB->t2.MaxSetupCount = 0; 3255 + pSMB->t2.Reserved = 0; 3256 + pSMB->t2.Flags = 0; 3257 + pSMB->t2.Timeout = 0; 3258 + pSMB->t2.Reserved2 = 0; 3259 + pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3260 + Fid) - 4); 3261 + pSMB->t2.DataCount = 0; 3262 + pSMB->t2.DataOffset = 0; 3263 + pSMB->t2.SetupCount = 1; 3264 + pSMB->t2.Reserved3 = 0; 3265 + pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3266 + byte_count = params + 1 /* pad */ ; 3267 + pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3268 + pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3269 + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3270 + pSMB->Pad = 0; 3271 + pSMB->Fid = netfid; 3272 + pSMB->hdr.smb_buf_length += byte_count; 3273 + 3274 + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3275 + (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3276 + if (rc) { 3277 + cFYI(1, ("Send error in QPathInfo = %d", rc)); 3278 + } else { /* decode response */ 3279 + rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3280 + 3281 + if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3282 + rc = -EIO; 3283 + else if (pSMBr->ByteCount < 40) 3284 + rc = -EIO; /* bad smb */ 3285 + else if (pFindData) { 3286 + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3287 + memcpy((char *) pFindData, 3288 + (char *) &pSMBr->hdr.Protocol + 3289 + data_offset, sizeof(FILE_ALL_INFO)); 3290 + } else 3291 + rc = -ENOMEM; 3292 + } 3293 + cifs_buf_release(pSMB); 3294 + if (rc == -EAGAIN) 3295 + goto QFileInfoRetry; 3296 + 3297 + return rc; 3298 + } 3235 3299 3236 3300 int 3237 3301 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, ··· 3394 3330 cifs_buf_release(pSMB); 3395 3331 if (rc == -EAGAIN) 3396 3332 goto QPathInfoRetry; 3333 + 3334 + return rc; 3335 + } 3336 + 3337 + int 3338 + CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 3339 + u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3340 + { 3341 + struct smb_t2_qfi_req *pSMB = NULL; 3342 + struct smb_t2_qfi_rsp *pSMBr = NULL; 3343 + int rc = 0; 3344 + int bytes_returned; 3345 + __u16 params, byte_count; 3346 + 3347 + UnixQFileInfoRetry: 3348 + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3349 + (void **) &pSMBr); 3350 + if (rc) 3351 + return rc; 3352 + 3353 + params = 2 /* level */ + 2 /* fid */; 3354 + pSMB->t2.TotalDataCount = 0; 3355 + pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3356 + /* BB find exact max data count below from sess structure BB */ 3357 + pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3358 + pSMB->t2.MaxSetupCount = 0; 3359 + pSMB->t2.Reserved = 0; 3360 + pSMB->t2.Flags = 0; 3361 + pSMB->t2.Timeout = 0; 3362 + pSMB->t2.Reserved2 = 0; 3363 + pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3364 + Fid) - 4); 3365 + pSMB->t2.DataCount = 0; 3366 + pSMB->t2.DataOffset = 0; 3367 + pSMB->t2.SetupCount = 1; 3368 + pSMB->t2.Reserved3 = 0; 3369 + pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3370 + byte_count = params + 1 /* pad */ ; 3371 + pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3372 + pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3373 + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3374 + pSMB->Pad = 0; 3375 + pSMB->Fid = netfid; 3376 + pSMB->hdr.smb_buf_length += byte_count; 3377 + 3378 + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3379 + (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3380 + if (rc) { 3381 + cFYI(1, ("Send error in QPathInfo = %d", rc)); 3382 + } else { /* decode response */ 3383 + rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3384 + 3385 + if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { 3386 + cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n" 3387 + "Unix Extensions can be disabled on mount " 3388 + "by specifying the nosfu mount option.")); 3389 + rc = -EIO; /* bad smb */ 3390 + } else { 3391 + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3392 + memcpy((char *) pFindData, 3393 + (char *) &pSMBr->hdr.Protocol + 3394 + data_offset, 3395 + sizeof(FILE_UNIX_BASIC_INFO)); 3396 + } 3397 + } 3398 + 3399 + cifs_buf_release(pSMB); 3400 + if (rc == -EAGAIN) 3401 + goto UnixQFileInfoRetry; 3397 3402 3398 3403 return rc; 3399 3404 }
+1 -1
fs/cifs/dir.c
··· 739 739 int isValid = 1; 740 740 741 741 if (direntry->d_inode) { 742 - if (cifs_revalidate(direntry)) 742 + if (cifs_revalidate_dentry(direntry)) 743 743 return 0; 744 744 } else { 745 745 cFYI(1, ("neg dentry 0x%p name = %s",
+3 -4
fs/cifs/file.c
··· 219 219 cFYI(1, ("inode unchanged on server")); 220 220 } else { 221 221 if (file->f_path.dentry->d_inode->i_mapping) { 222 - /* BB no need to lock inode until after invalidate 223 - since namei code should already have it locked? */ 222 + /* BB no need to lock inode until after invalidate 223 + since namei code should already have it locked? */ 224 224 rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); 225 225 if (rc != 0) 226 226 CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; ··· 1890 1890 1891 1891 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) 1892 1892 { 1893 - struct dentry *dentry = file->f_path.dentry; 1894 1893 int rc, xid; 1895 1894 1896 1895 xid = GetXid(); 1897 - rc = cifs_revalidate(dentry); 1896 + rc = cifs_revalidate_file(file); 1898 1897 if (rc) { 1899 1898 cFYI(1, ("Validation prior to mmap failed, error=%d", rc)); 1900 1899 FreeXid(xid);
+185 -114
fs/cifs/inode.c
··· 77 77 } 78 78 } 79 79 80 + /* check inode attributes against fattr. If they don't match, tag the 81 + * inode for cache invalidation 82 + */ 83 + static void 84 + cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) 85 + { 86 + struct cifsInodeInfo *cifs_i = CIFS_I(inode); 87 + 88 + cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid)); 89 + 90 + if (inode->i_state & I_NEW) { 91 + cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid)); 92 + return; 93 + } 94 + 95 + /* don't bother with revalidation if we have an oplock */ 96 + if (cifs_i->clientCanCacheRead) { 97 + cFYI(1, ("%s: inode %llu is oplocked", __func__, 98 + cifs_i->uniqueid)); 99 + return; 100 + } 101 + 102 + /* revalidate if mtime or size have changed */ 103 + if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && 104 + cifs_i->server_eof == fattr->cf_eof) { 105 + cFYI(1, ("%s: inode %llu is unchanged", __func__, 106 + cifs_i->uniqueid)); 107 + return; 108 + } 109 + 110 + cFYI(1, ("%s: invalidating inode %llu mapping", __func__, 111 + cifs_i->uniqueid)); 112 + cifs_i->invalid_mapping = true; 113 + } 114 + 80 115 /* populate an inode with info from a cifs_fattr struct */ 81 116 void 82 117 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) ··· 119 84 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 120 85 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 121 86 unsigned long oldtime = cifs_i->time; 87 + 88 + cifs_revalidate_cache(inode, fattr); 122 89 123 90 inode->i_atime = fattr->cf_atime; 124 91 inode->i_mtime = fattr->cf_mtime; ··· 266 229 fattr->cf_mtime = CURRENT_TIME; 267 230 fattr->cf_nlink = 2; 268 231 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; 232 + } 233 + 234 + int cifs_get_file_info_unix(struct file *filp) 235 + { 236 + int rc; 237 + int xid; 238 + FILE_UNIX_BASIC_INFO find_data; 239 + struct cifs_fattr fattr; 240 + struct inode *inode = filp->f_path.dentry->d_inode; 241 + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 242 + struct cifsTconInfo *tcon = cifs_sb->tcon; 243 + struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; 244 + 245 + xid = GetXid(); 246 + rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); 247 + if (!rc) { 248 + cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); 249 + } else if (rc == -EREMOTE) { 250 + cifs_create_dfs_fattr(&fattr, inode->i_sb); 251 + rc = 0; 252 + } 253 + 254 + cifs_fattr_to_inode(inode, &fattr); 255 + FreeXid(xid); 256 + return rc; 269 257 } 270 258 271 259 int cifs_get_inode_info_unix(struct inode **pinode, ··· 492 430 493 431 fattr->cf_uid = cifs_sb->mnt_uid; 494 432 fattr->cf_gid = cifs_sb->mnt_gid; 433 + } 434 + 435 + int cifs_get_file_info(struct file *filp) 436 + { 437 + int rc; 438 + int xid; 439 + FILE_ALL_INFO find_data; 440 + struct cifs_fattr fattr; 441 + struct inode *inode = filp->f_path.dentry->d_inode; 442 + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 443 + struct cifsTconInfo *tcon = cifs_sb->tcon; 444 + struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; 445 + 446 + xid = GetXid(); 447 + rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); 448 + if (rc == -EOPNOTSUPP || rc == -EINVAL) { 449 + /* 450 + * FIXME: legacy server -- fall back to path-based call? 451 + * for now, just skip revalidating and mark inode for 452 + * immediate reval. 453 + */ 454 + rc = 0; 455 + CIFS_I(inode)->time = 0; 456 + goto cgfi_exit; 457 + } else if (rc == -EREMOTE) { 458 + cifs_create_dfs_fattr(&fattr, inode->i_sb); 459 + rc = 0; 460 + } else if (rc) 461 + goto cgfi_exit; 462 + 463 + /* 464 + * don't bother with SFU junk here -- just mark inode as needing 465 + * revalidation. 466 + */ 467 + cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false); 468 + fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; 469 + fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; 470 + cifs_fattr_to_inode(inode, &fattr); 471 + cgfi_exit: 472 + FreeXid(xid); 473 + return rc; 495 474 } 496 475 497 476 int cifs_get_inode_info(struct inode **pinode, ··· 1492 1389 return rc; 1493 1390 } 1494 1391 1495 - int cifs_revalidate(struct dentry *direntry) 1392 + static bool 1393 + cifs_inode_needs_reval(struct inode *inode) 1394 + { 1395 + struct cifsInodeInfo *cifs_i = CIFS_I(inode); 1396 + 1397 + if (cifs_i->clientCanCacheRead) 1398 + return false; 1399 + 1400 + if (!lookupCacheEnabled) 1401 + return true; 1402 + 1403 + if (cifs_i->time == 0) 1404 + return true; 1405 + 1406 + /* FIXME: the actimeo should be tunable */ 1407 + if (time_after_eq(jiffies, cifs_i->time + HZ)) 1408 + return true; 1409 + 1410 + return false; 1411 + } 1412 + 1413 + /* check invalid_mapping flag and zap the cache if it's set */ 1414 + static void 1415 + cifs_invalidate_mapping(struct inode *inode) 1416 + { 1417 + int rc; 1418 + struct cifsInodeInfo *cifs_i = CIFS_I(inode); 1419 + 1420 + cifs_i->invalid_mapping = false; 1421 + 1422 + /* write back any cached data */ 1423 + if (inode->i_mapping && inode->i_mapping->nrpages != 0) { 1424 + rc = filemap_write_and_wait(inode->i_mapping); 1425 + if (rc) 1426 + cifs_i->write_behind_rc = rc; 1427 + } 1428 + invalidate_remote_inode(inode); 1429 + } 1430 + 1431 + int cifs_revalidate_file(struct file *filp) 1432 + { 1433 + int rc = 0; 1434 + struct inode *inode = filp->f_path.dentry->d_inode; 1435 + 1436 + if (!cifs_inode_needs_reval(inode)) 1437 + goto check_inval; 1438 + 1439 + if (CIFS_SB(inode->i_sb)->tcon->unix_ext) 1440 + rc = cifs_get_file_info_unix(filp); 1441 + else 1442 + rc = cifs_get_file_info(filp); 1443 + 1444 + check_inval: 1445 + if (CIFS_I(inode)->invalid_mapping) 1446 + cifs_invalidate_mapping(inode); 1447 + 1448 + return rc; 1449 + } 1450 + 1451 + /* revalidate a dentry's inode attributes */ 1452 + int cifs_revalidate_dentry(struct dentry *dentry) 1496 1453 { 1497 1454 int xid; 1498 - int rc = 0, wbrc = 0; 1499 - char *full_path; 1500 - struct cifs_sb_info *cifs_sb; 1501 - struct cifsInodeInfo *cifsInode; 1502 - loff_t local_size; 1503 - struct timespec local_mtime; 1504 - bool invalidate_inode = false; 1455 + int rc = 0; 1456 + char *full_path = NULL; 1457 + struct inode *inode = dentry->d_inode; 1458 + struct super_block *sb = dentry->d_sb; 1505 1459 1506 - if (direntry->d_inode == NULL) 1460 + if (inode == NULL) 1507 1461 return -ENOENT; 1508 - 1509 - cifsInode = CIFS_I(direntry->d_inode); 1510 - 1511 - if (cifsInode == NULL) 1512 - return -ENOENT; 1513 - 1514 - /* no sense revalidating inode info on file that no one can write */ 1515 - if (CIFS_I(direntry->d_inode)->clientCanCacheRead) 1516 - return rc; 1517 1462 1518 1463 xid = GetXid(); 1519 1464 1520 - cifs_sb = CIFS_SB(direntry->d_sb); 1465 + if (!cifs_inode_needs_reval(inode)) 1466 + goto check_inval; 1521 1467 1522 1468 /* can not safely grab the rename sem here if rename calls revalidate 1523 1469 since that would deadlock */ 1524 - full_path = build_path_from_dentry(direntry); 1470 + full_path = build_path_from_dentry(dentry); 1525 1471 if (full_path == NULL) { 1526 1472 rc = -ENOMEM; 1527 - FreeXid(xid); 1528 - return rc; 1473 + goto check_inval; 1529 1474 } 1475 + 1530 1476 cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " 1531 - "jiffies %ld", full_path, direntry->d_inode, 1532 - direntry->d_inode->i_count.counter, direntry, 1533 - direntry->d_time, jiffies)); 1477 + "jiffies %ld", full_path, inode, inode->i_count.counter, 1478 + dentry, dentry->d_time, jiffies)); 1534 1479 1535 - if (cifsInode->time == 0) { 1536 - /* was set to zero previously to force revalidate */ 1537 - } else if (time_before(jiffies, cifsInode->time + HZ) && 1538 - lookupCacheEnabled) { 1539 - if ((S_ISREG(direntry->d_inode->i_mode) == 0) || 1540 - (direntry->d_inode->i_nlink == 1)) { 1541 - kfree(full_path); 1542 - FreeXid(xid); 1543 - return rc; 1544 - } else { 1545 - cFYI(1, ("Have to revalidate file due to hardlinks")); 1546 - } 1547 - } 1480 + if (CIFS_SB(sb)->tcon->unix_ext) 1481 + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 1482 + else 1483 + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 1484 + xid, NULL); 1548 1485 1549 - /* save mtime and size */ 1550 - local_mtime = direntry->d_inode->i_mtime; 1551 - local_size = direntry->d_inode->i_size; 1552 - 1553 - if (cifs_sb->tcon->unix_ext) { 1554 - rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, 1555 - direntry->d_sb, xid); 1556 - if (rc) { 1557 - cFYI(1, ("error on getting revalidate info %d", rc)); 1558 - /* if (rc != -ENOENT) 1559 - rc = 0; */ /* BB should we cache info on 1560 - certain errors? */ 1561 - } 1562 - } else { 1563 - rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, 1564 - direntry->d_sb, xid, NULL); 1565 - if (rc) { 1566 - cFYI(1, ("error on getting revalidate info %d", rc)); 1567 - /* if (rc != -ENOENT) 1568 - rc = 0; */ /* BB should we cache info on 1569 - certain errors? */ 1570 - } 1571 - } 1572 - /* should we remap certain errors, access denied?, to zero */ 1573 - 1574 - /* if not oplocked, we invalidate inode pages if mtime or file size 1575 - had changed on server */ 1576 - 1577 - if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) && 1578 - (local_size == direntry->d_inode->i_size)) { 1579 - cFYI(1, ("cifs_revalidate - inode unchanged")); 1580 - } else { 1581 - /* file may have changed on server */ 1582 - if (cifsInode->clientCanCacheRead) { 1583 - /* no need to invalidate inode pages since we were the 1584 - only ones who could have modified the file and the 1585 - server copy is staler than ours */ 1586 - } else { 1587 - invalidate_inode = true; 1588 - } 1589 - } 1590 - 1591 - /* can not grab this sem since kernel filesys locking documentation 1592 - indicates i_mutex may be taken by the kernel on lookup and rename 1593 - which could deadlock if we grab the i_mutex here as well */ 1594 - /* mutex_lock(&direntry->d_inode->i_mutex);*/ 1595 - /* need to write out dirty pages here */ 1596 - if (direntry->d_inode->i_mapping) { 1597 - /* do we need to lock inode until after invalidate completes 1598 - below? */ 1599 - wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping); 1600 - if (wbrc) 1601 - CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; 1602 - } 1603 - if (invalidate_inode) { 1604 - /* shrink_dcache not necessary now that cifs dentry ops 1605 - are exported for negative dentries */ 1606 - /* if (S_ISDIR(direntry->d_inode->i_mode)) 1607 - shrink_dcache_parent(direntry); */ 1608 - if (S_ISREG(direntry->d_inode->i_mode)) { 1609 - if (direntry->d_inode->i_mapping) { 1610 - wbrc = filemap_fdatawait(direntry->d_inode->i_mapping); 1611 - if (wbrc) 1612 - CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; 1613 - } 1614 - /* may eventually have to do this for open files too */ 1615 - if (list_empty(&(cifsInode->openFileList))) { 1616 - /* changed on server - flush read ahead pages */ 1617 - cFYI(1, ("Invalidating read ahead data on " 1618 - "closed file")); 1619 - invalidate_remote_inode(direntry->d_inode); 1620 - } 1621 - } 1622 - } 1623 - /* mutex_unlock(&direntry->d_inode->i_mutex); */ 1486 + check_inval: 1487 + if (CIFS_I(inode)->invalid_mapping) 1488 + cifs_invalidate_mapping(inode); 1624 1489 1625 1490 kfree(full_path); 1626 1491 FreeXid(xid); ··· 1598 1527 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1599 1528 struct kstat *stat) 1600 1529 { 1601 - int err = cifs_revalidate(dentry); 1530 + int err = cifs_revalidate_dentry(dentry); 1602 1531 if (!err) { 1603 1532 generic_fillattr(dentry->d_inode, stat); 1604 1533 stat->blksize = CIFS_MAX_MSGSIZE;