aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-12-05 14:15:30 -0500
committerSteve French <sfrench@us.ibm.com>2005-12-05 14:15:30 -0500
commitc89a86bb96307019867d11874ef0b86adaa0598e (patch)
treec44c1a825e8a143a4c52bcb8692292aeb77fa64e /fs
parent07475ffba5800c53573180dd521273642adcd0e9 (diff)
parente4f5c82a92c2a546a16af1614114eec19120e40a (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/inode.c55
-rw-r--r--fs/nfs/nfs4proc.c11
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/write.c6
5 files changed, 39 insertions, 37 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7370583b61e5..c0d1a214572c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1287,6 +1287,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
1287 nfs_begin_data_update(dentry->d_inode); 1287 nfs_begin_data_update(dentry->d_inode);
1288 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, 1288 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
1289 dir, &qsilly); 1289 dir, &qsilly);
1290 nfs_mark_for_revalidate(dentry->d_inode);
1290 nfs_end_data_update(dentry->d_inode); 1291 nfs_end_data_update(dentry->d_inode);
1291 } else 1292 } else
1292 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, 1293 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
@@ -1334,6 +1335,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1334 /* The VFS may want to delete this inode */ 1335 /* The VFS may want to delete this inode */
1335 if (error == 0) 1336 if (error == 0)
1336 inode->i_nlink--; 1337 inode->i_nlink--;
1338 nfs_mark_for_revalidate(inode);
1337 nfs_end_data_update(inode); 1339 nfs_end_data_update(inode);
1338 } else 1340 } else
1339 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1341 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1556,6 +1558,7 @@ go_ahead:
1556 nfs_begin_data_update(old_inode); 1558 nfs_begin_data_update(old_inode);
1557 error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, 1559 error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
1558 new_dir, &new_dentry->d_name); 1560 new_dir, &new_dentry->d_name);
1561 nfs_mark_for_revalidate(old_inode);
1559 nfs_end_data_update(old_inode); 1562 nfs_end_data_update(old_inode);
1560 nfs_end_data_update(new_dir); 1563 nfs_end_data_update(new_dir);
1561 nfs_end_data_update(old_dir); 1564 nfs_end_data_update(old_dir);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index aaab1a5ac461..afd75d0463fd 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -54,7 +54,7 @@
54#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 54#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
55 55
56static void nfs_invalidate_inode(struct inode *); 56static void nfs_invalidate_inode(struct inode *);
57static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); 57static int nfs_update_inode(struct inode *, struct nfs_fattr *);
58 58
59static struct inode *nfs_alloc_inode(struct super_block *sb); 59static struct inode *nfs_alloc_inode(struct super_block *sb);
60static void nfs_destroy_inode(struct inode *); 60static void nfs_destroy_inode(struct inode *);
@@ -1080,8 +1080,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1080 int status = -ESTALE; 1080 int status = -ESTALE;
1081 struct nfs_fattr fattr; 1081 struct nfs_fattr fattr;
1082 struct nfs_inode *nfsi = NFS_I(inode); 1082 struct nfs_inode *nfsi = NFS_I(inode);
1083 unsigned long verifier;
1084 unsigned long cache_validity;
1085 1083
1086 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 1084 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
1087 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); 1085 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
@@ -1106,8 +1104,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1106 } 1104 }
1107 } 1105 }
1108 1106
1109 /* Protect against RPC races by saving the change attribute */
1110 verifier = nfs_save_change_attribute(inode);
1111 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); 1107 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
1112 if (status != 0) { 1108 if (status != 0) {
1113 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", 1109 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -1122,7 +1118,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1122 } 1118 }
1123 1119
1124 spin_lock(&inode->i_lock); 1120 spin_lock(&inode->i_lock);
1125 status = nfs_update_inode(inode, &fattr, verifier); 1121 status = nfs_update_inode(inode, &fattr);
1126 if (status) { 1122 if (status) {
1127 spin_unlock(&inode->i_lock); 1123 spin_unlock(&inode->i_lock);
1128 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", 1124 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
@@ -1130,20 +1126,11 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1130 (long long)NFS_FILEID(inode), status); 1126 (long long)NFS_FILEID(inode), status);
1131 goto out; 1127 goto out;
1132 } 1128 }
1133 cache_validity = nfsi->cache_validity;
1134 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1135
1136 /*
1137 * We may need to keep the attributes marked as invalid if
1138 * we raced with nfs_end_attr_update().
1139 */
1140 if (time_after_eq(verifier, nfsi->cache_change_attribute))
1141 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1142 spin_unlock(&inode->i_lock); 1129 spin_unlock(&inode->i_lock);
1143 1130
1144 nfs_revalidate_mapping(inode, inode->i_mapping); 1131 nfs_revalidate_mapping(inode, inode->i_mapping);
1145 1132
1146 if (cache_validity & NFS_INO_INVALID_ACL) 1133 if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
1147 nfs_zap_acl_cache(inode); 1134 nfs_zap_acl_cache(inode);
1148 1135
1149 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", 1136 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
@@ -1346,10 +1333,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1346 return 0; 1333 return 0;
1347 spin_lock(&inode->i_lock); 1334 spin_lock(&inode->i_lock);
1348 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1335 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1349 if (nfs_verify_change_attribute(inode, fattr->time_start))
1350 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1351 if (time_after(fattr->time_start, nfsi->last_updated)) 1336 if (time_after(fattr->time_start, nfsi->last_updated))
1352 status = nfs_update_inode(inode, fattr, fattr->time_start); 1337 status = nfs_update_inode(inode, fattr);
1353 else 1338 else
1354 status = nfs_check_inode_attributes(inode, fattr); 1339 status = nfs_check_inode_attributes(inode, fattr);
1355 1340
@@ -1375,10 +1360,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1375 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; 1360 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
1376 goto out; 1361 goto out;
1377 } 1362 }
1378 status = nfs_update_inode(inode, fattr, fattr->time_start); 1363 status = nfs_update_inode(inode, fattr);
1379 if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
1380 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
1381 nfsi->cache_change_attribute = jiffies;
1382out: 1364out:
1383 spin_unlock(&inode->i_lock); 1365 spin_unlock(&inode->i_lock);
1384 return status; 1366 return status;
@@ -1396,12 +1378,12 @@ out:
1396 * 1378 *
1397 * A very similar scenario holds for the dir cache. 1379 * A very similar scenario holds for the dir cache.
1398 */ 1380 */
1399static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) 1381static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1400{ 1382{
1401 struct nfs_inode *nfsi = NFS_I(inode); 1383 struct nfs_inode *nfsi = NFS_I(inode);
1402 loff_t cur_isize, new_isize; 1384 loff_t cur_isize, new_isize;
1403 unsigned int invalid = 0; 1385 unsigned int invalid = 0;
1404 int data_unstable; 1386 int data_stable;
1405 1387
1406 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 1388 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
1407 __FUNCTION__, inode->i_sb->s_id, inode->i_ino, 1389 __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
@@ -1432,8 +1414,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1432 nfsi->last_updated = jiffies; 1414 nfsi->last_updated = jiffies;
1433 1415
1434 /* Are we racing with known updates of the metadata on the server? */ 1416 /* Are we racing with known updates of the metadata on the server? */
1435 data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || 1417 data_stable = nfs_verify_change_attribute(inode, fattr->time_start);
1436 (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)); 1418 if (data_stable)
1419 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1437 1420
1438 /* Check if our cached file size is stale */ 1421 /* Check if our cached file size is stale */
1439 new_isize = nfs_size_to_loff_t(fattr->size); 1422 new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1442,7 +1425,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1442 /* Do we perhaps have any outstanding writes? */ 1425 /* Do we perhaps have any outstanding writes? */
1443 if (nfsi->npages == 0) { 1426 if (nfsi->npages == 0) {
1444 /* No, but did we race with nfs_end_data_update()? */ 1427 /* No, but did we race with nfs_end_data_update()? */
1445 if (time_after_eq(verifier, nfsi->cache_change_attribute)) { 1428 if (data_stable) {
1446 inode->i_size = new_isize; 1429 inode->i_size = new_isize;
1447 invalid |= NFS_INO_INVALID_DATA; 1430 invalid |= NFS_INO_INVALID_DATA;
1448 } 1431 }
@@ -1451,6 +1434,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1451 inode->i_size = new_isize; 1434 inode->i_size = new_isize;
1452 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1435 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1453 } 1436 }
1437 nfsi->cache_change_attribute = jiffies;
1454 dprintk("NFS: isize change on server for file %s/%ld\n", 1438 dprintk("NFS: isize change on server for file %s/%ld\n",
1455 inode->i_sb->s_id, inode->i_ino); 1439 inode->i_sb->s_id, inode->i_ino);
1456 } 1440 }
@@ -1460,8 +1444,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1460 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1444 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1461 dprintk("NFS: mtime change on server for file %s/%ld\n", 1445 dprintk("NFS: mtime change on server for file %s/%ld\n",
1462 inode->i_sb->s_id, inode->i_ino); 1446 inode->i_sb->s_id, inode->i_ino);
1463 if (!data_unstable) 1447 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1464 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1448 nfsi->cache_change_attribute = jiffies;
1465 } 1449 }
1466 1450
1467 if ((fattr->valid & NFS_ATTR_FATTR_V4) 1451 if ((fattr->valid & NFS_ATTR_FATTR_V4)
@@ -1469,15 +1453,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1469 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1453 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1470 inode->i_sb->s_id, inode->i_ino); 1454 inode->i_sb->s_id, inode->i_ino);
1471 nfsi->change_attr = fattr->change_attr; 1455 nfsi->change_attr = fattr->change_attr;
1472 if (!data_unstable) 1456 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1473 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1457 nfsi->cache_change_attribute = jiffies;
1474 } 1458 }
1475 1459
1476 /* If ctime has changed we should definitely clear access+acl caches */ 1460 /* If ctime has changed we should definitely clear access+acl caches */
1477 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1461 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1478 if (!data_unstable) 1462 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1479 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1480 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1463 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1464 nfsi->cache_change_attribute = jiffies;
1481 } 1465 }
1482 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1466 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1483 1467
@@ -1515,6 +1499,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1515 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1499 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
1516 || S_ISLNK(inode->i_mode))) 1500 || S_ISLNK(inode->i_mode)))
1517 invalid &= ~NFS_INO_INVALID_DATA; 1501 invalid &= ~NFS_INO_INVALID_DATA;
1502 if (data_stable)
1503 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
1518 if (!nfs_have_delegation(inode, FMODE_READ)) 1504 if (!nfs_have_delegation(inode, FMODE_READ))
1519 nfsi->cache_validity |= invalid; 1505 nfsi->cache_validity |= invalid;
1520 1506
@@ -2066,6 +2052,7 @@ static struct inode *nfs_alloc_inode(struct super_block *sb)
2066 return NULL; 2052 return NULL;
2067 nfsi->flags = 0UL; 2053 nfsi->flags = 0UL;
2068 nfsi->cache_validity = 0UL; 2054 nfsi->cache_validity = 0UL;
2055 nfsi->cache_change_attribute = jiffies;
2069#ifdef CONFIG_NFS_V3_ACL 2056#ifdef CONFIG_NFS_V3_ACL
2070 nfsi->acl_access = ERR_PTR(-EAGAIN); 2057 nfsi->acl_access = ERR_PTR(-EAGAIN);
2071 nfsi->acl_default = ERR_PTR(-EAGAIN); 2058 nfsi->acl_default = ERR_PTR(-EAGAIN);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 60e0dd800cc3..f988a9417b13 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1506,10 +1506,15 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
1506 dprintk("NFS call write %d @ %Ld\n", wdata->args.count, 1506 dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
1507 (long long) wdata->args.offset); 1507 (long long) wdata->args.offset);
1508 1508
1509 wdata->args.bitmask = server->attr_bitmask;
1510 wdata->res.server = server;
1509 nfs_fattr_init(fattr); 1511 nfs_fattr_init(fattr);
1510 status = rpc_call_sync(server->client, &msg, rpcflags); 1512 status = rpc_call_sync(server->client, &msg, rpcflags);
1511 dprintk("NFS reply write: %d\n", status); 1513 dprintk("NFS reply write: %d\n", status);
1512 return status; 1514 if (status < 0)
1515 return status;
1516 nfs_post_op_update_inode(inode, fattr);
1517 return wdata->res.count;
1513} 1518}
1514 1519
1515static int nfs4_proc_write(struct nfs_write_data *wdata) 1520static int nfs4_proc_write(struct nfs_write_data *wdata)
@@ -1540,9 +1545,13 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
1540 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, 1545 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
1541 (long long) cdata->args.offset); 1546 (long long) cdata->args.offset);
1542 1547
1548 cdata->args.bitmask = server->attr_bitmask;
1549 cdata->res.server = server;
1543 nfs_fattr_init(fattr); 1550 nfs_fattr_init(fattr);
1544 status = rpc_call_sync(server->client, &msg, 0); 1551 status = rpc_call_sync(server->client, &msg, 0);
1545 dprintk("NFS reply commit: %d\n", status); 1552 dprintk("NFS reply commit: %d\n", status);
1553 if (status >= 0)
1554 nfs_post_op_update_inode(inode, fattr);
1546 return status; 1555 return status;
1547} 1556}
1548 1557
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index a48a003242c0..e1e3ca5d746b 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -375,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
375 375
376 dprintk("NFS call link %s\n", name->name); 376 dprintk("NFS call link %s\n", name->name);
377 status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); 377 status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
378 nfs_mark_for_revalidate(inode);
378 nfs_mark_for_revalidate(dir); 379 nfs_mark_for_revalidate(dir);
379 dprintk("NFS reply link: %d\n", status); 380 dprintk("NFS reply link: %d\n", status);
380 return status; 381 return status;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8f71e766cc5d..3107908e5f3f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -189,6 +189,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
189 (long long)NFS_FILEID(inode), 189 (long long)NFS_FILEID(inode),
190 count, (long long)(page_offset(page) + offset)); 190 count, (long long)(page_offset(page) + offset));
191 191
192 set_page_writeback(page);
192 nfs_begin_data_update(inode); 193 nfs_begin_data_update(inode);
193 do { 194 do {
194 if (count < wsize) 195 if (count < wsize)
@@ -221,6 +222,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
221 222
222io_error: 223io_error:
223 nfs_end_data_update(inode); 224 nfs_end_data_update(inode);
225 end_page_writeback(page);
224 nfs_writedata_free(wdata); 226 nfs_writedata_free(wdata);
225 return written ? written : result; 227 return written ? written : result;
226} 228}
@@ -929,7 +931,7 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how)
929 atomic_set(&req->wb_complete, requests); 931 atomic_set(&req->wb_complete, requests);
930 932
931 ClearPageError(page); 933 ClearPageError(page);
932 SetPageWriteback(page); 934 set_page_writeback(page);
933 offset = 0; 935 offset = 0;
934 nbytes = req->wb_bytes; 936 nbytes = req->wb_bytes;
935 do { 937 do {
@@ -992,7 +994,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
992 nfs_list_remove_request(req); 994 nfs_list_remove_request(req);
993 nfs_list_add_request(req, &data->pages); 995 nfs_list_add_request(req, &data->pages);
994 ClearPageError(req->wb_page); 996 ClearPageError(req->wb_page);
995 SetPageWriteback(req->wb_page); 997 set_page_writeback(req->wb_page);
996 *pages++ = req->wb_page; 998 *pages++ = req->wb_page;
997 count += req->wb_bytes; 999 count += req->wb_bytes;
998 } 1000 }