aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-27 22:12:39 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-27 22:12:39 -0400
commitdecf491f3076190262d4c649bed877650623903a (patch)
tree8f67577349fe451b0267b68435db1578ec1273a4 /fs
parent33801147a8fda6b04d7e9afe1d42f1c01d3d6837 (diff)
NFS: Don't let nfs_end_data_update() clobber attribute update information
Since we almost always call nfs_end_data_update() after we called nfs_refresh_inode(), we now end up marking the inode metadata as needing revalidation immediately after having updated it. This patch rearranges things so that we mark the inode as needing revalidation _before_ we call nfs_refresh_inode() on those operations that need it. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/inode.c38
-rw-r--r--fs/nfs/nfs3proc.c30
-rw-r--r--fs/nfs/nfs4proc.c3
-rw-r--r--fs/nfs/proc.c16
4 files changed, 63 insertions, 24 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b7d4f8f13ac2..6b3156e15350 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1236,13 +1236,12 @@ void nfs_end_data_update(struct inode *inode)
1236 struct nfs_inode *nfsi = NFS_I(inode); 1236 struct nfs_inode *nfsi = NFS_I(inode);
1237 1237
1238 if (!nfs_have_delegation(inode, FMODE_READ)) { 1238 if (!nfs_have_delegation(inode, FMODE_READ)) {
1239 /* Mark the attribute cache for revalidation */ 1239 /* Directories and symlinks: invalidate page cache */
1240 spin_lock(&inode->i_lock); 1240 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
1241 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1241 spin_lock(&inode->i_lock);
1242 /* Directories and symlinks: invalidate page cache too */
1243 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
1244 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 1242 nfsi->cache_validity |= NFS_INO_INVALID_DATA;
1245 spin_unlock(&inode->i_lock); 1243 spin_unlock(&inode->i_lock);
1244 }
1246 } 1245 }
1247 nfsi->cache_change_attribute = jiffies; 1246 nfsi->cache_change_attribute = jiffies;
1248 atomic_dec(&nfsi->data_updates); 1247 atomic_dec(&nfsi->data_updates);
@@ -1360,6 +1359,33 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1360 return status; 1359 return status;
1361} 1360}
1362 1361
1362/**
1363 * nfs_post_op_update_inode - try to update the inode attribute cache
1364 * @inode - pointer to inode
1365 * @fattr - updated attributes
1366 *
1367 * After an operation that has changed the inode metadata, mark the
1368 * attribute cache as being invalid, then try to update it.
1369 */
1370int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1371{
1372 struct nfs_inode *nfsi = NFS_I(inode);
1373 int status = 0;
1374
1375 spin_lock(&inode->i_lock);
1376 if (unlikely((fattr->valid & NFS_ATTR_FATTR) == 0)) {
1377 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
1378 goto out;
1379 }
1380 status = nfs_update_inode(inode, fattr, fattr->time_start);
1381 if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
1382 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
1383 nfsi->cache_change_attribute = jiffies;
1384out:
1385 spin_unlock(&inode->i_lock);
1386 return status;
1387}
1388
1363/* 1389/*
1364 * Many nfs protocol calls return the new file attributes after 1390 * Many nfs protocol calls return the new file attributes after
1365 * an operation. Here we update the inode to reflect the state 1391 * an operation. Here we update the inode to reflect the state
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 4b1b48b139f6..92c870d19ccd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -266,7 +266,7 @@ static int nfs3_proc_write(struct nfs_write_data *wdata)
266 nfs_fattr_init(fattr); 266 nfs_fattr_init(fattr);
267 status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); 267 status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
268 if (status >= 0) 268 if (status >= 0)
269 nfs_refresh_inode(inode, fattr); 269 nfs_post_op_update_inode(inode, fattr);
270 dprintk("NFS reply write: %d\n", status); 270 dprintk("NFS reply write: %d\n", status);
271 return status < 0? status : wdata->res.count; 271 return status < 0? status : wdata->res.count;
272} 272}
@@ -288,7 +288,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
288 nfs_fattr_init(fattr); 288 nfs_fattr_init(fattr);
289 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 289 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
290 if (status >= 0) 290 if (status >= 0)
291 nfs_refresh_inode(inode, fattr); 291 nfs_post_op_update_inode(inode, fattr);
292 dprintk("NFS reply commit: %d\n", status); 292 dprintk("NFS reply commit: %d\n", status);
293 return status; 293 return status;
294} 294}
@@ -332,7 +332,7 @@ again:
332 nfs_fattr_init(&dir_attr); 332 nfs_fattr_init(&dir_attr);
333 nfs_fattr_init(&fattr); 333 nfs_fattr_init(&fattr);
334 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0); 334 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
335 nfs_refresh_inode(dir, &dir_attr); 335 nfs_post_op_update_inode(dir, &dir_attr);
336 336
337 /* If the server doesn't support the exclusive creation semantics, 337 /* If the server doesn't support the exclusive creation semantics,
338 * try again with simple 'guarded' mode. */ 338 * try again with simple 'guarded' mode. */
@@ -403,7 +403,7 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
403 dprintk("NFS call remove %s\n", name->name); 403 dprintk("NFS call remove %s\n", name->name);
404 nfs_fattr_init(&dir_attr); 404 nfs_fattr_init(&dir_attr);
405 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 405 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
406 nfs_refresh_inode(dir, &dir_attr); 406 nfs_post_op_update_inode(dir, &dir_attr);
407 dprintk("NFS reply remove: %d\n", status); 407 dprintk("NFS reply remove: %d\n", status);
408 return status; 408 return status;
409} 409}
@@ -439,7 +439,7 @@ nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
439 return 1; 439 return 1;
440 if (msg->rpc_argp) { 440 if (msg->rpc_argp) {
441 dir_attr = (struct nfs_fattr*)msg->rpc_resp; 441 dir_attr = (struct nfs_fattr*)msg->rpc_resp;
442 nfs_refresh_inode(dir->d_inode, dir_attr); 442 nfs_post_op_update_inode(dir->d_inode, dir_attr);
443 kfree(msg->rpc_argp); 443 kfree(msg->rpc_argp);
444 } 444 }
445 return 0; 445 return 0;
@@ -468,8 +468,8 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
468 nfs_fattr_init(&old_dir_attr); 468 nfs_fattr_init(&old_dir_attr);
469 nfs_fattr_init(&new_dir_attr); 469 nfs_fattr_init(&new_dir_attr);
470 status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0); 470 status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
471 nfs_refresh_inode(old_dir, &old_dir_attr); 471 nfs_post_op_update_inode(old_dir, &old_dir_attr);
472 nfs_refresh_inode(new_dir, &new_dir_attr); 472 nfs_post_op_update_inode(new_dir, &new_dir_attr);
473 dprintk("NFS reply rename: %d\n", status); 473 dprintk("NFS reply rename: %d\n", status);
474 return status; 474 return status;
475} 475}
@@ -494,8 +494,8 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
494 nfs_fattr_init(&dir_attr); 494 nfs_fattr_init(&dir_attr);
495 nfs_fattr_init(&fattr); 495 nfs_fattr_init(&fattr);
496 status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0); 496 status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
497 nfs_refresh_inode(dir, &dir_attr); 497 nfs_post_op_update_inode(dir, &dir_attr);
498 nfs_refresh_inode(inode, &fattr); 498 nfs_post_op_update_inode(inode, &fattr);
499 dprintk("NFS reply link: %d\n", status); 499 dprintk("NFS reply link: %d\n", status);
500 return status; 500 return status;
501} 501}
@@ -527,7 +527,7 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
527 nfs_fattr_init(&dir_attr); 527 nfs_fattr_init(&dir_attr);
528 nfs_fattr_init(fattr); 528 nfs_fattr_init(fattr);
529 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0); 529 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
530 nfs_refresh_inode(dir, &dir_attr); 530 nfs_post_op_update_inode(dir, &dir_attr);
531 dprintk("NFS reply symlink: %d\n", status); 531 dprintk("NFS reply symlink: %d\n", status);
532 return status; 532 return status;
533} 533}
@@ -558,7 +558,7 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
558 nfs_fattr_init(&dir_attr); 558 nfs_fattr_init(&dir_attr);
559 nfs_fattr_init(&fattr); 559 nfs_fattr_init(&fattr);
560 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0); 560 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
561 nfs_refresh_inode(dir, &dir_attr); 561 nfs_post_op_update_inode(dir, &dir_attr);
562 if (status != 0) 562 if (status != 0)
563 goto out; 563 goto out;
564 status = nfs_instantiate(dentry, &fhandle, &fattr); 564 status = nfs_instantiate(dentry, &fhandle, &fattr);
@@ -584,7 +584,7 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
584 dprintk("NFS call rmdir %s\n", name->name); 584 dprintk("NFS call rmdir %s\n", name->name);
585 nfs_fattr_init(&dir_attr); 585 nfs_fattr_init(&dir_attr);
586 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0); 586 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
587 nfs_refresh_inode(dir, &dir_attr); 587 nfs_post_op_update_inode(dir, &dir_attr);
588 dprintk("NFS reply rmdir: %d\n", status); 588 dprintk("NFS reply rmdir: %d\n", status);
589 return status; 589 return status;
590} 590}
@@ -679,7 +679,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
679 nfs_fattr_init(&dir_attr); 679 nfs_fattr_init(&dir_attr);
680 nfs_fattr_init(&fattr); 680 nfs_fattr_init(&fattr);
681 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); 681 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
682 nfs_refresh_inode(dir, &dir_attr); 682 nfs_post_op_update_inode(dir, &dir_attr);
683 if (status != 0) 683 if (status != 0)
684 goto out; 684 goto out;
685 status = nfs_instantiate(dentry, &fh, &fattr); 685 status = nfs_instantiate(dentry, &fh, &fattr);
@@ -775,7 +775,7 @@ nfs3_write_done(struct rpc_task *task)
775 return; 775 return;
776 data = (struct nfs_write_data *)task->tk_calldata; 776 data = (struct nfs_write_data *)task->tk_calldata;
777 if (task->tk_status >= 0) 777 if (task->tk_status >= 0)
778 nfs_refresh_inode(data->inode, data->res.fattr); 778 nfs_post_op_update_inode(data->inode, data->res.fattr);
779 nfs_writeback_done(task); 779 nfs_writeback_done(task);
780} 780}
781 781
@@ -819,7 +819,7 @@ nfs3_commit_done(struct rpc_task *task)
819 return; 819 return;
820 data = (struct nfs_write_data *)task->tk_calldata; 820 data = (struct nfs_write_data *)task->tk_calldata;
821 if (task->tk_status >= 0) 821 if (task->tk_status >= 0)
822 nfs_refresh_inode(data->inode, data->res.fattr); 822 nfs_post_op_update_inode(data->inode, data->res.fattr);
823 nfs_commit_done(task); 823 nfs_commit_done(task);
824} 824}
825 825
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2a759e8e387c..3274f2d354f3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -187,8 +187,11 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
187{ 187{
188 struct nfs_inode *nfsi = NFS_I(inode); 188 struct nfs_inode *nfsi = NFS_I(inode);
189 189
190 spin_lock(&inode->i_lock);
191 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
190 if (cinfo->before == nfsi->change_attr && cinfo->atomic) 192 if (cinfo->before == nfsi->change_attr && cinfo->atomic)
191 nfsi->change_attr = cinfo->after; 193 nfsi->change_attr = cinfo->after;
194 spin_unlock(&inode->i_lock);
192} 195}
193 196
194/* Helper for asynchronous RPC calls */ 197/* Helper for asynchronous RPC calls */
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 5ef28f08f424..a48a003242c0 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -206,7 +206,7 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
206 nfs_fattr_init(fattr); 206 nfs_fattr_init(fattr);
207 status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); 207 status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
208 if (status >= 0) { 208 if (status >= 0) {
209 nfs_refresh_inode(inode, fattr); 209 nfs_post_op_update_inode(inode, fattr);
210 wdata->res.count = wdata->args.count; 210 wdata->res.count = wdata->args.count;
211 wdata->verf.committed = NFS_FILE_SYNC; 211 wdata->verf.committed = NFS_FILE_SYNC;
212 } 212 }
@@ -275,6 +275,7 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
275 275
276 nfs_fattr_init(&fattr); 276 nfs_fattr_init(&fattr);
277 status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0); 277 status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
278 nfs_mark_for_revalidate(dir);
278 279
279 if (status == -EINVAL && S_ISFIFO(mode)) { 280 if (status == -EINVAL && S_ISFIFO(mode)) {
280 sattr->ia_mode = mode; 281 sattr->ia_mode = mode;
@@ -305,6 +306,7 @@ nfs_proc_remove(struct inode *dir, struct qstr *name)
305 306
306 dprintk("NFS call remove %s\n", name->name); 307 dprintk("NFS call remove %s\n", name->name);
307 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 308 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
309 nfs_mark_for_revalidate(dir);
308 310
309 dprintk("NFS reply remove: %d\n", status); 311 dprintk("NFS reply remove: %d\n", status);
310 return status; 312 return status;
@@ -331,8 +333,10 @@ nfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
331{ 333{
332 struct rpc_message *msg = &task->tk_msg; 334 struct rpc_message *msg = &task->tk_msg;
333 335
334 if (msg->rpc_argp) 336 if (msg->rpc_argp) {
337 nfs_mark_for_revalidate(dir->d_inode);
335 kfree(msg->rpc_argp); 338 kfree(msg->rpc_argp);
339 }
336 return 0; 340 return 0;
337} 341}
338 342
@@ -352,6 +356,8 @@ nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
352 356
353 dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); 357 dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
354 status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0); 358 status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
359 nfs_mark_for_revalidate(old_dir);
360 nfs_mark_for_revalidate(new_dir);
355 dprintk("NFS reply rename: %d\n", status); 361 dprintk("NFS reply rename: %d\n", status);
356 return status; 362 return status;
357} 363}
@@ -369,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
369 375
370 dprintk("NFS call link %s\n", name->name); 376 dprintk("NFS call link %s\n", name->name);
371 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(dir);
372 dprintk("NFS reply link: %d\n", status); 379 dprintk("NFS reply link: %d\n", status);
373 return status; 380 return status;
374} 381}
@@ -394,6 +401,7 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
394 nfs_fattr_init(fattr); 401 nfs_fattr_init(fattr);
395 fhandle->size = 0; 402 fhandle->size = 0;
396 status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0); 403 status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
404 nfs_mark_for_revalidate(dir);
397 dprintk("NFS reply symlink: %d\n", status); 405 dprintk("NFS reply symlink: %d\n", status);
398 return status; 406 return status;
399} 407}
@@ -418,6 +426,7 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
418 dprintk("NFS call mkdir %s\n", dentry->d_name.name); 426 dprintk("NFS call mkdir %s\n", dentry->d_name.name);
419 nfs_fattr_init(&fattr); 427 nfs_fattr_init(&fattr);
420 status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0); 428 status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
429 nfs_mark_for_revalidate(dir);
421 if (status == 0) 430 if (status == 0)
422 status = nfs_instantiate(dentry, &fhandle, &fattr); 431 status = nfs_instantiate(dentry, &fhandle, &fattr);
423 dprintk("NFS reply mkdir: %d\n", status); 432 dprintk("NFS reply mkdir: %d\n", status);
@@ -436,6 +445,7 @@ nfs_proc_rmdir(struct inode *dir, struct qstr *name)
436 445
437 dprintk("NFS call rmdir %s\n", name->name); 446 dprintk("NFS call rmdir %s\n", name->name);
438 status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0); 447 status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
448 nfs_mark_for_revalidate(dir);
439 dprintk("NFS reply rmdir: %d\n", status); 449 dprintk("NFS reply rmdir: %d\n", status);
440 return status; 450 return status;
441} 451}
@@ -579,7 +589,7 @@ nfs_write_done(struct rpc_task *task)
579 struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; 589 struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
580 590
581 if (task->tk_status >= 0) 591 if (task->tk_status >= 0)
582 nfs_refresh_inode(data->inode, data->res.fattr); 592 nfs_post_op_update_inode(data->inode, data->res.fattr);
583 nfs_writeback_done(task); 593 nfs_writeback_done(task);
584} 594}
585 595