init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg)
 {
        INIT_LIST_HEAD(&lseg->pls_list);
+       INIT_LIST_HEAD(&lseg->pls_lc_list);
        atomic_set(&lseg->pls_refcount, 1);
        smp_mb();
        set_bit(NFS_LSEG_VALID, &lseg->pls_flags);
 EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages);
 
 /*
- * Currently there is only one (whole file) write lseg.
+ * There can be multiple RW segments.
  */
-static struct pnfs_layout_segment *pnfs_list_write_lseg(struct inode *inode)
+static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
 {
-       struct pnfs_layout_segment *lseg, *rv = NULL;
+       struct pnfs_layout_segment *lseg;
 
-       list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list)
-               if (lseg->pls_range.iomode == IOMODE_RW)
-                       rv = lseg;
-       return rv;
+       list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
+               if (lseg->pls_range.iomode == IOMODE_RW &&
+                   test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
+                       list_add(&lseg->pls_lc_list, listp);
+       }
 }
 
 void
 
        spin_lock(&nfsi->vfs_inode.i_lock);
        if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
-               /* references matched in nfs4_layoutcommit_release */
-               get_lseg(wdata->lseg);
                mark_as_dirty = true;
                dprintk("%s: Set layoutcommit for inode %lu ",
                        __func__, wdata->inode->i_ino);
        }
+       if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &wdata->lseg->pls_flags)) {
+               /* references matched in nfs4_layoutcommit_release */
+               get_lseg(wdata->lseg);
+       }
        if (end_pos > nfsi->layout->plh_lwb)
                nfsi->layout->plh_lwb = end_pos;
        spin_unlock(&nfsi->vfs_inode.i_lock);
 {
        struct nfs4_layoutcommit_data *data;
        struct nfs_inode *nfsi = NFS_I(inode);
-       struct pnfs_layout_segment *lseg;
        loff_t end_pos;
        int status = 0;
 
                goto out;
        }
 
+       INIT_LIST_HEAD(&data->lseg_list);
        spin_lock(&inode->i_lock);
        if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
                spin_unlock(&inode->i_lock);
                kfree(data);
                goto out;
        }
-       /*
-        * Currently only one (whole file) write lseg which is referenced
-        * in pnfs_set_layoutcommit and will be found.
-        */
-       lseg = pnfs_list_write_lseg(inode);
+
+       pnfs_list_write_lseg(inode, &data->lseg_list);
 
        end_pos = nfsi->layout->plh_lwb;
        nfsi->layout->plh_lwb = 0;
        spin_unlock(&inode->i_lock);
 
        data->args.inode = inode;
-       data->lseg = lseg;
        data->cred = get_rpccred(nfsi->layout->plh_lc_cred);
        nfs_fattr_init(&data->fattr);
        data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;