diff options
-rw-r--r-- | fs/nfs/callback_proc.c | 14 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 4 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 3 |
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 | ||
1759 | static void | 1759 | void |
1760 | pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, | 1760 | pnfs_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, | |||
266 | int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 266 | int 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); |
269 | void pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, | ||
270 | struct list_head *tmp_list, | ||
271 | struct pnfs_layout_range *recall_range); | ||
269 | bool pnfs_roc(struct inode *ino); | 272 | bool pnfs_roc(struct inode *ino); |
270 | void pnfs_roc_release(struct inode *ino); | 273 | void pnfs_roc_release(struct inode *ino); |
271 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); | 274 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); |