aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/callback_proc.c14
-rw-r--r--fs/nfs/pnfs.c4
-rw-r--r--fs/nfs/pnfs.h3
3 files changed, 18 insertions, 3 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 716cbff24450..34852ece4057 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -181,9 +181,19 @@ static u32 initiate_file_draining(struct nfs_client *clp,
181 pnfs_layoutcommit_inode(ino, false); 181 pnfs_layoutcommit_inode(ino, false);
182 182
183 spin_lock(&ino->i_lock); 183 spin_lock(&ino->i_lock);
184 if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || 184 /*
185 pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, 185 * Enforce RFC5661 Section 12.5.5.2.1.5 (Bulk Recall and Return)
186 */
187 if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
188 rv = NFS4ERR_DELAY;
189 goto unlock;
190 }
191
192 if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list,
186 &args->cbl_range)) { 193 &args->cbl_range)) {
194 pnfs_mark_matching_lsegs_return(lo,
195 &free_me_list,
196 &args->cbl_range);
187 rv = NFS4ERR_DELAY; 197 rv = NFS4ERR_DELAY;
188 goto unlock; 198 goto unlock;
189 } 199 }
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index b3fb6bb02275..360fe95c97b5 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1756,7 +1756,7 @@ out_forget_reply:
1756 goto out; 1756 goto out;
1757} 1757}
1758 1758
1759static void 1759void
1760pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, 1760pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
1761 struct list_head *tmp_list, 1761 struct list_head *tmp_list,
1762 struct pnfs_layout_range *return_range) 1762 struct pnfs_layout_range *return_range)
@@ -1768,6 +1768,8 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
1768 if (list_empty(&lo->plh_segs)) 1768 if (list_empty(&lo->plh_segs))
1769 return; 1769 return;
1770 1770
1771 assert_spin_locked(&lo->plh_inode->i_lock);
1772
1771 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) 1773 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
1772 if (should_free_lseg(&lseg->pls_range, return_range)) { 1774 if (should_free_lseg(&lseg->pls_range, return_range)) {
1773 dprintk("%s: marking lseg %p iomode %d " 1775 dprintk("%s: marking lseg %p iomode %d "
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index be24a759b655..d93c2ebc0fd3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -266,6 +266,9 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
266int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, 266int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
267 struct list_head *tmp_list, 267 struct list_head *tmp_list,
268 struct pnfs_layout_range *recall_range); 268 struct pnfs_layout_range *recall_range);
269void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
270 struct list_head *tmp_list,
271 struct pnfs_layout_range *recall_range);
269bool pnfs_roc(struct inode *ino); 272bool pnfs_roc(struct inode *ino);
270void pnfs_roc_release(struct inode *ino); 273void pnfs_roc_release(struct inode *ino);
271void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); 274void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);