Skip to content

Commit 81b676b

Browse files
committed
Merge tag 'nfs-for-4.5-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfix and cleanup from Trond Myklebust: "Bugfix: - pNFS: Fix for missing layoutreturn calls Cleanup: - pNFS: rename NFS_LAYOUT_RETURN_BEFORE_CLOSE for code clarity" * tag 'nfs-for-4.5-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFS: Cleanup - rename NFS_LAYOUT_RETURN_BEFORE_CLOSE pNFS: Fix missing layoutreturn calls
2 parents ef582d0 + 2370abd commit 81b676b

File tree

4 files changed

+62
-68
lines changed

4 files changed

+62
-68
lines changed

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,7 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
12151215
hdr->pgio_mirror_idx + 1,
12161216
&hdr->pgio_mirror_idx))
12171217
goto out_eagain;
1218-
set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1218+
set_bit(NFS_LAYOUT_RETURN_REQUESTED,
12191219
&hdr->lseg->pls_layout->plh_flags);
12201220
pnfs_read_resend_pnfs(hdr);
12211221
return task->tk_status;

fs/nfs/flexfilelayout/flexfilelayoutdev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
412412
OP_ILLEGAL, GFP_NOIO);
413413
if (!fail_return) {
414414
if (ff_layout_has_available_ds(lseg))
415-
set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
415+
set_bit(NFS_LAYOUT_RETURN_REQUESTED,
416416
&lseg->pls_layout->plh_flags);
417417
else
418418
pnfs_error_mark_layout_for_return(ino, lseg);

fs/nfs/pnfs.c

Lines changed: 58 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ static DEFINE_SPINLOCK(pnfs_spinlock);
5252
*/
5353
static LIST_HEAD(pnfs_modules_tbl);
5454

55-
static int
56-
pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid,
57-
enum pnfs_iomode iomode, bool sync);
55+
static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo);
5856

5957
/* Return the registered pnfs layout driver module matching given id */
6058
static struct pnfs_layoutdriver_type *
@@ -243,6 +241,8 @@ pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
243241
{
244242
struct inode *inode = lo->plh_inode;
245243

244+
pnfs_layoutreturn_before_put_layout_hdr(lo);
245+
246246
if (atomic_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
247247
if (!list_empty(&lo->plh_segs))
248248
WARN_ONCE(1, "NFS: BUG unfreed layout segments.\n");
@@ -345,58 +345,6 @@ pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
345345
rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq);
346346
}
347347

348-
/* Return true if layoutreturn is needed */
349-
static bool
350-
pnfs_layout_need_return(struct pnfs_layout_hdr *lo,
351-
struct pnfs_layout_segment *lseg)
352-
{
353-
struct pnfs_layout_segment *s;
354-
355-
if (!test_and_clear_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags))
356-
return false;
357-
358-
list_for_each_entry(s, &lo->plh_segs, pls_list)
359-
if (s != lseg && test_bit(NFS_LSEG_LAYOUTRETURN, &s->pls_flags))
360-
return false;
361-
362-
return true;
363-
}
364-
365-
static bool
366-
pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo)
367-
{
368-
if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
369-
return false;
370-
lo->plh_return_iomode = 0;
371-
pnfs_get_layout_hdr(lo);
372-
clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags);
373-
return true;
374-
}
375-
376-
static void pnfs_layoutreturn_before_put_lseg(struct pnfs_layout_segment *lseg,
377-
struct pnfs_layout_hdr *lo, struct inode *inode)
378-
{
379-
lo = lseg->pls_layout;
380-
inode = lo->plh_inode;
381-
382-
spin_lock(&inode->i_lock);
383-
if (pnfs_layout_need_return(lo, lseg)) {
384-
nfs4_stateid stateid;
385-
enum pnfs_iomode iomode;
386-
bool send;
387-
388-
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
389-
iomode = lo->plh_return_iomode;
390-
send = pnfs_prepare_layoutreturn(lo);
391-
spin_unlock(&inode->i_lock);
392-
if (send) {
393-
/* Send an async layoutreturn so we dont deadlock */
394-
pnfs_send_layoutreturn(lo, &stateid, iomode, false);
395-
}
396-
} else
397-
spin_unlock(&inode->i_lock);
398-
}
399-
400348
void
401349
pnfs_put_lseg(struct pnfs_layout_segment *lseg)
402350
{
@@ -410,15 +358,8 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg)
410358
atomic_read(&lseg->pls_refcount),
411359
test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
412360

413-
/* Handle the case where refcount != 1 */
414-
if (atomic_add_unless(&lseg->pls_refcount, -1, 1))
415-
return;
416-
417361
lo = lseg->pls_layout;
418362
inode = lo->plh_inode;
419-
/* Do we need a layoutreturn? */
420-
if (test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags))
421-
pnfs_layoutreturn_before_put_lseg(lseg, lo, inode);
422363

423364
if (atomic_dec_and_lock(&lseg->pls_refcount, &inode->i_lock)) {
424365
if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags)) {
@@ -937,6 +878,17 @@ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
937878
rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
938879
}
939880

881+
static bool
882+
pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo)
883+
{
884+
if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
885+
return false;
886+
lo->plh_return_iomode = 0;
887+
pnfs_get_layout_hdr(lo);
888+
clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
889+
return true;
890+
}
891+
940892
static int
941893
pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid,
942894
enum pnfs_iomode iomode, bool sync)
@@ -971,6 +923,48 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid,
971923
return status;
972924
}
973925

926+
/* Return true if layoutreturn is needed */
927+
static bool
928+
pnfs_layout_need_return(struct pnfs_layout_hdr *lo)
929+
{
930+
struct pnfs_layout_segment *s;
931+
932+
if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
933+
return false;
934+
935+
/* Defer layoutreturn until all lsegs are done */
936+
list_for_each_entry(s, &lo->plh_segs, pls_list) {
937+
if (test_bit(NFS_LSEG_LAYOUTRETURN, &s->pls_flags))
938+
return false;
939+
}
940+
941+
return true;
942+
}
943+
944+
static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo)
945+
{
946+
struct inode *inode= lo->plh_inode;
947+
948+
if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
949+
return;
950+
spin_lock(&inode->i_lock);
951+
if (pnfs_layout_need_return(lo)) {
952+
nfs4_stateid stateid;
953+
enum pnfs_iomode iomode;
954+
bool send;
955+
956+
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
957+
iomode = lo->plh_return_iomode;
958+
send = pnfs_prepare_layoutreturn(lo);
959+
spin_unlock(&inode->i_lock);
960+
if (send) {
961+
/* Send an async layoutreturn so we dont deadlock */
962+
pnfs_send_layoutreturn(lo, &stateid, iomode, false);
963+
}
964+
} else
965+
spin_unlock(&inode->i_lock);
966+
}
967+
974968
/*
975969
* Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr
976970
* when the layout segment list is empty.
@@ -1091,7 +1085,7 @@ bool pnfs_roc(struct inode *ino)
10911085

10921086
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
10931087
/* always send layoutreturn if being marked so */
1094-
if (test_and_clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1088+
if (test_and_clear_bit(NFS_LAYOUT_RETURN_REQUESTED,
10951089
&lo->plh_flags))
10961090
layoutreturn = pnfs_prepare_layoutreturn(lo);
10971091

@@ -1772,7 +1766,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
17721766
pnfs_set_plh_return_iomode(lo, return_range->iomode);
17731767
if (!mark_lseg_invalid(lseg, tmp_list))
17741768
remaining++;
1775-
set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1769+
set_bit(NFS_LAYOUT_RETURN_REQUESTED,
17761770
&lo->plh_flags);
17771771
}
17781772
return remaining;

fs/nfs/pnfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ enum {
9494
NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */
9595
NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */
9696
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
97-
NFS_LAYOUT_RETURN, /* Return this layout ASAP */
98-
NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
97+
NFS_LAYOUT_RETURN, /* layoutreturn in progress */
98+
NFS_LAYOUT_RETURN_REQUESTED, /* Return this layout ASAP */
9999
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
100100
NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
101101
};

0 commit comments

Comments
 (0)