diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-27 22:12:39 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-27 22:12:39 -0400 |
commit | 33801147a8fda6b04d7e9afe1d42f1c01d3d6837 (patch) | |
tree | 5311fb4714f0a24b7d7666b04250205025e18d15 /fs/nfs/inode.c | |
parent | 913a70fc170530f7e1ff0693595155457cc6d0ca (diff) |
NFS: Optimise inode attribute cache updates
Allow nfs_refresh_inode() also to update attributes on the inode if the
RPC call was sent after the last call to nfs_update_inode().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 449df8c8aa31..b7d4f8f13ac2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -785,7 +785,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
785 | else | 785 | else |
786 | init_special_inode(inode, inode->i_mode, fattr->rdev); | 786 | init_special_inode(inode, inode->i_mode, fattr->rdev); |
787 | 787 | ||
788 | nfsi->read_cache_jiffies = fattr->timestamp; | 788 | nfsi->read_cache_jiffies = fattr->time_start; |
789 | nfsi->last_updated = jiffies; | ||
789 | inode->i_atime = fattr->atime; | 790 | inode->i_atime = fattr->atime; |
790 | inode->i_mtime = fattr->mtime; | 791 | inode->i_mtime = fattr->mtime; |
791 | inode->i_ctime = fattr->ctime; | 792 | inode->i_ctime = fattr->ctime; |
@@ -1120,14 +1121,15 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1120 | goto out; | 1121 | goto out; |
1121 | } | 1122 | } |
1122 | 1123 | ||
1124 | spin_lock(&inode->i_lock); | ||
1123 | status = nfs_update_inode(inode, &fattr, verifier); | 1125 | status = nfs_update_inode(inode, &fattr, verifier); |
1124 | if (status) { | 1126 | if (status) { |
1127 | spin_unlock(&inode->i_lock); | ||
1125 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", | 1128 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", |
1126 | inode->i_sb->s_id, | 1129 | inode->i_sb->s_id, |
1127 | (long long)NFS_FILEID(inode), status); | 1130 | (long long)NFS_FILEID(inode), status); |
1128 | goto out; | 1131 | goto out; |
1129 | } | 1132 | } |
1130 | spin_lock(&inode->i_lock); | ||
1131 | cache_validity = nfsi->cache_validity; | 1133 | cache_validity = nfsi->cache_validity; |
1132 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | 1134 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; |
1133 | 1135 | ||
@@ -1247,7 +1249,7 @@ void nfs_end_data_update(struct inode *inode) | |||
1247 | } | 1249 | } |
1248 | 1250 | ||
1249 | /** | 1251 | /** |
1250 | * nfs_refresh_inode - verify consistency of the inode attribute cache | 1252 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache |
1251 | * @inode - pointer to inode | 1253 | * @inode - pointer to inode |
1252 | * @fattr - updated attributes | 1254 | * @fattr - updated attributes |
1253 | * | 1255 | * |
@@ -1255,13 +1257,12 @@ void nfs_end_data_update(struct inode *inode) | |||
1255 | * so that fattr carries weak cache consistency data, then it may | 1257 | * so that fattr carries weak cache consistency data, then it may |
1256 | * also update the ctime/mtime/change_attribute. | 1258 | * also update the ctime/mtime/change_attribute. |
1257 | */ | 1259 | */ |
1258 | int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | 1260 | static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr) |
1259 | { | 1261 | { |
1260 | struct nfs_inode *nfsi = NFS_I(inode); | 1262 | struct nfs_inode *nfsi = NFS_I(inode); |
1261 | loff_t cur_size, new_isize; | 1263 | loff_t cur_size, new_isize; |
1262 | int data_unstable; | 1264 | int data_unstable; |
1263 | 1265 | ||
1264 | spin_lock(&inode->i_lock); | ||
1265 | 1266 | ||
1266 | /* Are we in the process of updating data on the server? */ | 1267 | /* Are we in the process of updating data on the server? */ |
1267 | data_unstable = nfs_caches_unstable(inode); | 1268 | data_unstable = nfs_caches_unstable(inode); |
@@ -1325,11 +1326,40 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1325 | if (!timespec_equal(&inode->i_atime, &fattr->atime)) | 1326 | if (!timespec_equal(&inode->i_atime, &fattr->atime)) |
1326 | nfsi->cache_validity |= NFS_INO_INVALID_ATIME; | 1327 | nfsi->cache_validity |= NFS_INO_INVALID_ATIME; |
1327 | 1328 | ||
1328 | nfsi->read_cache_jiffies = fattr->timestamp; | 1329 | nfsi->read_cache_jiffies = fattr->time_start; |
1329 | spin_unlock(&inode->i_lock); | ||
1330 | return 0; | 1330 | return 0; |
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | /** | ||
1334 | * nfs_refresh_inode - try to update the inode attribute cache | ||
1335 | * @inode - pointer to inode | ||
1336 | * @fattr - updated attributes | ||
1337 | * | ||
1338 | * Check that an RPC call that returned attributes has not overlapped with | ||
1339 | * other recent updates of the inode metadata, then decide whether it is | ||
1340 | * safe to do a full update of the inode attributes, or whether just to | ||
1341 | * call nfs_check_inode_attributes. | ||
1342 | */ | ||
1343 | int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | ||
1344 | { | ||
1345 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1346 | int status; | ||
1347 | |||
1348 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | ||
1349 | return 0; | ||
1350 | spin_lock(&inode->i_lock); | ||
1351 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | ||
1352 | if (nfs_verify_change_attribute(inode, fattr->time_start)) | ||
1353 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1354 | if (time_after(fattr->time_start, nfsi->last_updated)) | ||
1355 | status = nfs_update_inode(inode, fattr, fattr->time_start); | ||
1356 | else | ||
1357 | status = nfs_check_inode_attributes(inode, fattr); | ||
1358 | |||
1359 | spin_unlock(&inode->i_lock); | ||
1360 | return status; | ||
1361 | } | ||
1362 | |||
1333 | /* | 1363 | /* |
1334 | * Many nfs protocol calls return the new file attributes after | 1364 | * Many nfs protocol calls return the new file attributes after |
1335 | * an operation. Here we update the inode to reflect the state | 1365 | * an operation. Here we update the inode to reflect the state |
@@ -1365,20 +1395,17 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1365 | goto out_err; | 1395 | goto out_err; |
1366 | } | 1396 | } |
1367 | 1397 | ||
1368 | spin_lock(&inode->i_lock); | ||
1369 | |||
1370 | /* | 1398 | /* |
1371 | * Make sure the inode's type hasn't changed. | 1399 | * Make sure the inode's type hasn't changed. |
1372 | */ | 1400 | */ |
1373 | if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { | 1401 | if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) |
1374 | spin_unlock(&inode->i_lock); | ||
1375 | goto out_changed; | 1402 | goto out_changed; |
1376 | } | ||
1377 | 1403 | ||
1378 | /* | 1404 | /* |
1379 | * Update the read time so we don't revalidate too often. | 1405 | * Update the read time so we don't revalidate too often. |
1380 | */ | 1406 | */ |
1381 | nfsi->read_cache_jiffies = fattr->timestamp; | 1407 | nfsi->read_cache_jiffies = fattr->time_start; |
1408 | nfsi->last_updated = jiffies; | ||
1382 | 1409 | ||
1383 | /* Are we racing with known updates of the metadata on the server? */ | 1410 | /* Are we racing with known updates of the metadata on the server? */ |
1384 | data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || | 1411 | data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || |
@@ -1467,7 +1494,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1467 | if (!nfs_have_delegation(inode, FMODE_READ)) | 1494 | if (!nfs_have_delegation(inode, FMODE_READ)) |
1468 | nfsi->cache_validity |= invalid; | 1495 | nfsi->cache_validity |= invalid; |
1469 | 1496 | ||
1470 | spin_unlock(&inode->i_lock); | ||
1471 | return 0; | 1497 | return 0; |
1472 | out_changed: | 1498 | out_changed: |
1473 | /* | 1499 | /* |