aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorPeng Tao <bergwolf@gmail.com>2011-10-23 23:21:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-10-31 11:51:28 -0400
commit92407e75ce45b41c46944891711fd8faf0714d84 (patch)
tree6616482a99f4b328f2a2acc853af20f273faf08f /fs/nfs/pnfs.c
parente20de377578e9504f8467c05ab1db98b4935d4ed (diff)
nfs4: serialize layoutcommit
Current pnfs_layoutcommit_inode can not handle parallel layoutcommit. And as Trond suggested , there is no need for client to optimize for parallel layoutcommit. So add NFS_INO_LAYOUTCOMMITTING flag to mark inflight layoutcommit and serialize lalyoutcommit with it. Also mark_inode_dirty_sync if pnfs_layoutcommit_inode fails to issue layoutcommit. Reported-by: Vitaliy Gusev <gusev.vitaliy@nexenta.com> Signed-off-by: Peng Tao <peng_tao@emc.com> Signed-off-by: Jim Rees <rees@umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index ee73d9a4f700..a2478bc74442 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1443,17 +1443,31 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
1443 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */ 1443 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
1444 data = kzalloc(sizeof(*data), GFP_NOFS); 1444 data = kzalloc(sizeof(*data), GFP_NOFS);
1445 if (!data) { 1445 if (!data) {
1446 mark_inode_dirty_sync(inode);
1447 status = -ENOMEM; 1446 status = -ENOMEM;
1448 goto out; 1447 goto out;
1449 } 1448 }
1450 1449
1450 if (!test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
1451 goto out_free;
1452
1453 if (test_and_set_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags)) {
1454 if (!sync) {
1455 status = -EAGAIN;
1456 goto out_free;
1457 }
1458 status = wait_on_bit_lock(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING,
1459 nfs_wait_bit_killable, TASK_KILLABLE);
1460 if (status)
1461 goto out_free;
1462 }
1463
1451 INIT_LIST_HEAD(&data->lseg_list); 1464 INIT_LIST_HEAD(&data->lseg_list);
1452 spin_lock(&inode->i_lock); 1465 spin_lock(&inode->i_lock);
1453 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { 1466 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
1467 clear_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags);
1454 spin_unlock(&inode->i_lock); 1468 spin_unlock(&inode->i_lock);
1455 kfree(data); 1469 wake_up_bit(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING);
1456 goto out; 1470 goto out_free;
1457 } 1471 }
1458 1472
1459 pnfs_list_write_lseg(inode, &data->lseg_list); 1473 pnfs_list_write_lseg(inode, &data->lseg_list);
@@ -1475,6 +1489,11 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
1475 1489
1476 status = nfs4_proc_layoutcommit(data, sync); 1490 status = nfs4_proc_layoutcommit(data, sync);
1477out: 1491out:
1492 if (status)
1493 mark_inode_dirty_sync(inode);
1478 dprintk("<-- %s status %d\n", __func__, status); 1494 dprintk("<-- %s status %d\n", __func__, status);
1479 return status; 1495 return status;
1496out_free:
1497 kfree(data);
1498 goto out;
1480} 1499}