aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-02-12 07:44:16 -0500
committerSteve French <sfrench@us.ibm.com>2010-03-05 23:37:05 -0500
commitdf2cf170c823ba779ca339e3ede347c87f4dc6a9 (patch)
tree9ea1ababe413a518afb3de89dadeba73db082850 /fs/cifs/inode.c
parent64ba9926759792cf7b95f823402e2781edd1b5d4 (diff)
cifs: overhaul cifs_revalidate and rename to cifs_revalidate_dentry
cifs_revalidate is renamed to cifs_revalidate_dentry as a later patch will add a by-filehandle variant. Add a new "invalid_mapping" flag to the cifsInodeInfo that indicates that the pagecache is considered invalid. Add a new routine to check inode attributes whenever they're updated and set that flag if the inode has changed on the server. cifs_revalidate_dentry is then changed to just update the attrcache if needed and then to zap the pagecache if it's not valid. There are some other behavior changes in here as well. Open files are now allowed to have their caches invalidated. I see no reason why we'd want to keep stale data around just because a file is open. Also, cifs_revalidate_cache uses the server_eof for revalidating the file size since that should more closely match the size of the file on the server. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c211
1 files changed, 98 insertions, 113 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8bdbc818164c..f050dba920cb 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -77,6 +77,41 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
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 */
83static void
84cifs_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/* populate an inode with info from a cifs_fattr struct */ 115/* populate an inode with info from a cifs_fattr struct */
81void 116void
82cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) 117cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
@@ -85,6 +120,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
85 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 120 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
86 unsigned long oldtime = cifs_i->time; 121 unsigned long oldtime = cifs_i->time;
87 122
123 cifs_revalidate_cache(inode, fattr);
124
88 inode->i_atime = fattr->cf_atime; 125 inode->i_atime = fattr->cf_atime;
89 inode->i_mtime = fattr->cf_mtime; 126 inode->i_mtime = fattr->cf_mtime;
90 inode->i_ctime = fattr->cf_ctime; 127 inode->i_ctime = fattr->cf_ctime;
@@ -1389,135 +1426,83 @@ cifs_rename_exit:
1389 return rc; 1426 return rc;
1390} 1427}
1391 1428
1392int cifs_revalidate(struct dentry *direntry) 1429static bool
1430cifs_inode_needs_reval(struct inode *inode)
1393{ 1431{
1394 int xid; 1432 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1395 int rc = 0, wbrc = 0;
1396 char *full_path;
1397 struct cifs_sb_info *cifs_sb;
1398 struct cifsInodeInfo *cifsInode;
1399 loff_t local_size;
1400 struct timespec local_mtime;
1401 bool invalidate_inode = false;
1402 1433
1403 if (direntry->d_inode == NULL) 1434 if (cifs_i->clientCanCacheRead)
1404 return -ENOENT; 1435 return false;
1405 1436
1406 cifsInode = CIFS_I(direntry->d_inode); 1437 if (!lookupCacheEnabled)
1438 return true;
1407 1439
1408 if (cifsInode == NULL) 1440 if (cifs_i->time == 0)
1409 return -ENOENT; 1441 return true;
1410 1442
1411 /* no sense revalidating inode info on file that no one can write */ 1443 /* FIXME: the actimeo should be tunable */
1412 if (CIFS_I(direntry->d_inode)->clientCanCacheRead) 1444 if (time_after_eq(jiffies, cifs_i->time + HZ))
1413 return rc; 1445 return true;
1446
1447 return false;
1448}
1449
1450/* check invalid_mapping flag and zap the cache if it's set */
1451static void
1452cifs_invalidate_mapping(struct inode *inode)
1453{
1454 int rc;
1455 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1456
1457 cifs_i->invalid_mapping = false;
1458
1459 /* write back any cached data */
1460 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1461 rc = filemap_write_and_wait(inode->i_mapping);
1462 if (rc)
1463 cifs_i->write_behind_rc = rc;
1464 }
1465 invalidate_remote_inode(inode);
1466}
1467
1468/* revalidate a dentry's inode attributes */
1469int cifs_revalidate_dentry(struct dentry *dentry)
1470{
1471 int xid;
1472 int rc = 0;
1473 char *full_path = NULL;
1474 struct inode *inode = dentry->d_inode;
1475 struct super_block *sb = dentry->d_sb;
1476
1477 if (inode == NULL)
1478 return -ENOENT;
1414 1479
1415 xid = GetXid(); 1480 xid = GetXid();
1416 1481
1417 cifs_sb = CIFS_SB(direntry->d_sb); 1482 if (!cifs_inode_needs_reval(inode))
1483 goto check_inval;
1418 1484
1419 /* can not safely grab the rename sem here if rename calls revalidate 1485 /* can not safely grab the rename sem here if rename calls revalidate
1420 since that would deadlock */ 1486 since that would deadlock */
1421 full_path = build_path_from_dentry(direntry); 1487 full_path = build_path_from_dentry(dentry);
1422 if (full_path == NULL) { 1488 if (full_path == NULL) {
1423 rc = -ENOMEM; 1489 rc = -ENOMEM;
1424 FreeXid(xid); 1490 goto check_inval;
1425 return rc;
1426 } 1491 }
1427 cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1428 "jiffies %ld", full_path, direntry->d_inode,
1429 direntry->d_inode->i_count.counter, direntry,
1430 direntry->d_time, jiffies));
1431
1432 if (cifsInode->time == 0) {
1433 /* was set to zero previously to force revalidate */
1434 } else if (time_before(jiffies, cifsInode->time + HZ) &&
1435 lookupCacheEnabled) {
1436 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1437 (direntry->d_inode->i_nlink == 1)) {
1438 kfree(full_path);
1439 FreeXid(xid);
1440 return rc;
1441 } else {
1442 cFYI(1, ("Have to revalidate file due to hardlinks"));
1443 }
1444 }
1445
1446 /* save mtime and size */
1447 local_mtime = direntry->d_inode->i_mtime;
1448 local_size = direntry->d_inode->i_size;
1449 1492
1450 if (cifs_sb->tcon->unix_ext) { 1493 cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1451 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, 1494 "jiffies %ld", full_path, inode, inode->i_count.counter,
1452 direntry->d_sb, xid); 1495 dentry, dentry->d_time, jiffies));
1453 if (rc) {
1454 cFYI(1, ("error on getting revalidate info %d", rc));
1455/* if (rc != -ENOENT)
1456 rc = 0; */ /* BB should we cache info on
1457 certain errors? */
1458 }
1459 } else {
1460 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1461 direntry->d_sb, xid, NULL);
1462 if (rc) {
1463 cFYI(1, ("error on getting revalidate info %d", rc));
1464/* if (rc != -ENOENT)
1465 rc = 0; */ /* BB should we cache info on
1466 certain errors? */
1467 }
1468 }
1469 /* should we remap certain errors, access denied?, to zero */
1470
1471 /* if not oplocked, we invalidate inode pages if mtime or file size
1472 had changed on server */
1473 1496
1474 if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) && 1497 if (CIFS_SB(sb)->tcon->unix_ext)
1475 (local_size == direntry->d_inode->i_size)) { 1498 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1476 cFYI(1, ("cifs_revalidate - inode unchanged")); 1499 else
1477 } else { 1500 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1478 /* file may have changed on server */ 1501 xid, NULL);
1479 if (cifsInode->clientCanCacheRead) {
1480 /* no need to invalidate inode pages since we were the
1481 only ones who could have modified the file and the
1482 server copy is staler than ours */
1483 } else {
1484 invalidate_inode = true;
1485 }
1486 }
1487 1502
1488 /* can not grab this sem since kernel filesys locking documentation 1503check_inval:
1489 indicates i_mutex may be taken by the kernel on lookup and rename 1504 if (CIFS_I(inode)->invalid_mapping)
1490 which could deadlock if we grab the i_mutex here as well */ 1505 cifs_invalidate_mapping(inode);
1491/* mutex_lock(&direntry->d_inode->i_mutex);*/
1492 /* need to write out dirty pages here */
1493 if (direntry->d_inode->i_mapping) {
1494 /* do we need to lock inode until after invalidate completes
1495 below? */
1496 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1497 if (wbrc)
1498 CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1499 }
1500 if (invalidate_inode) {
1501 /* shrink_dcache not necessary now that cifs dentry ops
1502 are exported for negative dentries */
1503/* if (S_ISDIR(direntry->d_inode->i_mode))
1504 shrink_dcache_parent(direntry); */
1505 if (S_ISREG(direntry->d_inode->i_mode)) {
1506 if (direntry->d_inode->i_mapping) {
1507 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1508 if (wbrc)
1509 CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1510 }
1511 /* may eventually have to do this for open files too */
1512 if (list_empty(&(cifsInode->openFileList))) {
1513 /* changed on server - flush read ahead pages */
1514 cFYI(1, ("Invalidating read ahead data on "
1515 "closed file"));
1516 invalidate_remote_inode(direntry->d_inode);
1517 }
1518 }
1519 }
1520/* mutex_unlock(&direntry->d_inode->i_mutex); */
1521 1506
1522 kfree(full_path); 1507 kfree(full_path);
1523 FreeXid(xid); 1508 FreeXid(xid);
@@ -1527,7 +1512,7 @@ int cifs_revalidate(struct dentry *direntry)
1527int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1512int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1528 struct kstat *stat) 1513 struct kstat *stat)
1529{ 1514{
1530 int err = cifs_revalidate(dentry); 1515 int err = cifs_revalidate_dentry(dentry);
1531 if (!err) { 1516 if (!err) {
1532 generic_fillattr(dentry->d_inode, stat); 1517 generic_fillattr(dentry->d_inode, stat);
1533 stat->blksize = CIFS_MAX_MSGSIZE; 1518 stat->blksize = CIFS_MAX_MSGSIZE;