2010-10-13 18:43:17

by Andy Adamson

[permalink] [raw]
Subject: [PATCH 1/2] pnfs_submit: fix layoutreturn layout stateid processing

From: Andy Adamson <[email protected]>

Add missing layoutreturn stateid update.
This patch also enforces the following rfc 5661 requirement:

section 12.5.4
"For LAYOUTRETURN results, the client MUST delete the range from its
record of what ranges of the file's layout it had before using the
seqid."

Reported-by: P.B.Shelley <[email protected]>
Signed-off-by: Andy Adamson <[email protected]>
---
fs/nfs/nfs4proc.c | 10 +++++-----
fs/nfs/pnfs.c | 7 +++----
fs/nfs/pnfs.h | 3 ++-
3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7727f59..4c56d9b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5678,11 +5678,11 @@ static void nfs4_layoutreturn_release(void *calldata)
dprintk("--> %s return_type %d lo %p\n", __func__,
lrp->args.return_type, lo);

- if (lrp->args.return_type == RETURN_FILE) {
- if (!lrp->res.lrs_present)
- pnfs_invalidate_layout_stateid(lo);
- pnfs_layoutreturn_release(lo, &lrp->args.range);
- }
+ pnfs_layoutreturn_release(lo, &lrp->args.range);
+ if (!lrp->res.lrs_present)
+ pnfs_invalidate_layout_stateid(lo);
+ else
+ pnfs_set_layout_stateid(lo, &lrp->res.stateid);
kfree(calldata);
dprintk("<-- %s\n", __func__);
}
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index eb4dfdf..124d3ca 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -400,8 +400,7 @@ pnfs_layoutreturn_release(struct pnfs_layout_hdr *lo,
LIST_HEAD(tmp_list);

spin_lock(&nfsi->vfs_inode.i_lock);
- if (range)
- pnfs_clear_lseg_list(lo, &tmp_list, range);
+ pnfs_clear_lseg_list(lo, &tmp_list, range);
put_layout_hdr_locked(lo); /* Matched in _pnfs_return_layout */
spin_unlock(&nfsi->vfs_inode.i_lock);
pnfs_free_lseg_list(&tmp_list);
@@ -460,7 +459,7 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
*
* lo->stateid could be the open stateid, in which case we just use what given.
*/
-static void
+void
pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
const nfs4_stateid *new)
{
@@ -625,7 +624,7 @@ return_layout(struct inode *ino, struct pnfs_layout_range *range,
lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
if (lrp == NULL) {
if (lo && (type == RETURN_FILE))
- pnfs_layoutreturn_release(lo, NULL);
+ put_layout_hdr(lo->inode);
goto out;
}
lrp->args.reclaim = 0;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 235709e..3fd2bc3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -210,7 +210,8 @@ void pnfs_destroy_all_layouts(struct nfs_client *);
void put_layout_hdr(struct inode *inode);
void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
struct nfs4_state *open_state);
-
+void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
+ const nfs4_stateid *new);

static inline bool
has_layout(struct nfs_inode *nfsi)
--
1.6.6



2010-10-13 19:36:57

by Fred Isaman

[permalink] [raw]
Subject: Re: [PATCH 1/2] pnfs_submit: fix layoutreturn layout stateid processing

On Tue, Oct 12, 2010 at 6:13 AM, <[email protected]> wrote:
> From: Andy Adamson <[email protected]>
>
> Add missing layoutreturn stateid update.
> This patch also enforces the following rfc 5661 requirement:
>
> section 12.5.4

Should this be 12.5.3?

> ? "For LAYOUTRETURN results, the client MUST delete the range from its
> ? record of what ranges of the file's layout it had before using the
> ? seqid."
>
> Reported-by: P.B.Shelley <[email protected]>
> Signed-off-by: Andy Adamson <[email protected]>
> ---
> ?fs/nfs/nfs4proc.c | ? 10 +++++-----
> ?fs/nfs/pnfs.c ? ? | ? ?7 +++----
> ?fs/nfs/pnfs.h ? ? | ? ?3 ++-
> ?3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 7727f59..4c56d9b 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -5678,11 +5678,11 @@ static void nfs4_layoutreturn_release(void *calldata)
> ? ? ? ?dprintk("--> %s return_type %d lo %p\n", __func__,
> ? ? ? ? ? ? ? ?lrp->args.return_type, lo);
>
> - ? ? ? if (lrp->args.return_type == RETURN_FILE) {
> - ? ? ? ? ? ? ? if (!lrp->res.lrs_present)
> - ? ? ? ? ? ? ? ? ? ? ? pnfs_invalidate_layout_stateid(lo);
> - ? ? ? ? ? ? ? pnfs_layoutreturn_release(lo, &lrp->args.range);
> - ? ? ? }
> + ? ? ? pnfs_layoutreturn_release(lo, &lrp->args.range);

args.range (and lo itself) only make sense in RETURN_FILE case.

> + ? ? ? if (!lrp->res.lrs_present)
> + ? ? ? ? ? ? ? pnfs_invalidate_layout_stateid(lo);
> + ? ? ? else
> + ? ? ? ? ? ? ? pnfs_set_layout_stateid(lo, &lrp->res.stateid);
> ? ? ? ?kfree(calldata);
> ? ? ? ?dprintk("<-- %s\n", __func__);
> ?}
> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
> index eb4dfdf..124d3ca 100644
> --- a/fs/nfs/pnfs.c
> +++ b/fs/nfs/pnfs.c
> @@ -400,8 +400,7 @@ pnfs_layoutreturn_release(struct pnfs_layout_hdr *lo,
> ? ? ? ?LIST_HEAD(tmp_list);
>
> ? ? ? ?spin_lock(&nfsi->vfs_inode.i_lock);
> - ? ? ? if (range)
> - ? ? ? ? ? ? ? pnfs_clear_lseg_list(lo, &tmp_list, range);
> + ? ? ? pnfs_clear_lseg_list(lo, &tmp_list, range);
> ? ? ? ?put_layout_hdr_locked(lo); /* Matched in _pnfs_return_layout */
> ? ? ? ?spin_unlock(&nfsi->vfs_inode.i_lock);
> ? ? ? ?pnfs_free_lseg_list(&tmp_list);
> @@ -460,7 +459,7 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
> ?*
> ?* lo->stateid could be the open stateid, in which case we just use what given.
> ?*/
> -static void
> +void
> ?pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
> ? ? ? ? ? ? ? ? ? ? ? ?const nfs4_stateid *new)
> ?{
> @@ -625,7 +624,7 @@ return_layout(struct inode *ino, struct pnfs_layout_range *range,
> ? ? ? ?lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
> ? ? ? ?if (lrp == NULL) {
> ? ? ? ? ? ? ? ?if (lo && (type == RETURN_FILE))
> - ? ? ? ? ? ? ? ? ? ? ? pnfs_layoutreturn_release(lo, NULL);
> + ? ? ? ? ? ? ? ? ? ? ? put_layout_hdr(lo->inode);
> ? ? ? ? ? ? ? ?goto out;
> ? ? ? ?}
> ? ? ? ?lrp->args.reclaim = 0;
> diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
> index 235709e..3fd2bc3 100644
> --- a/fs/nfs/pnfs.h
> +++ b/fs/nfs/pnfs.h
> @@ -210,7 +210,8 @@ void pnfs_destroy_all_layouts(struct nfs_client *);
> ?void put_layout_hdr(struct inode *inode);
> ?void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct nfs4_state *open_state);
> -
> +void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const nfs4_stateid *new);
>
> ?static inline bool
> ?has_layout(struct nfs_inode *nfsi)
> --
> 1.6.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

2010-10-13 18:43:19

by Andy Adamson

[permalink] [raw]
Subject: [PATCH 2/2] pnfs_submit: replace pnfs_layoutget_release with put_layout_hdr

From: Andy Adamson <[email protected]>

They are the same function.

Signed-off-by: Andy Adamson <[email protected]>
---
fs/nfs/nfs4proc.c | 2 +-
fs/nfs/pnfs.c | 13 +------------
fs/nfs/pnfs.h | 1 -
3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4c56d9b..9322e67 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5474,7 +5474,7 @@ static void nfs4_layoutget_release(void *calldata)
struct nfs4_layoutget *lgp = calldata;

dprintk("--> %s\n", __func__);
- pnfs_layoutget_release(NFS_I(lgp->args.inode)->layout);
+ put_layout_hdr(lgp->args.inode);
if (lgp->res.layout.buf != NULL)
free_page((unsigned long) lgp->res.layout.buf);
put_nfs_open_context(lgp->args.ctx);
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 124d3ca..52e56a1 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -381,17 +381,6 @@ pnfs_free_lseg_list(struct list_head *tmp_list)
}
}

-
-void
-pnfs_layoutget_release(struct pnfs_layout_hdr *lo)
-{
- struct nfs_inode *nfsi = NFS_I(lo->inode);
-
- spin_lock(&nfsi->vfs_inode.i_lock);
- put_layout_hdr_locked(lo); /* Matched in _pnfs_update_layout */
- spin_unlock(&nfsi->vfs_inode.i_lock);
-}
-
void
pnfs_layoutreturn_release(struct pnfs_layout_hdr *lo,
struct pnfs_layout_range *range)
@@ -541,7 +530,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
BUG_ON(ctx == NULL);
lgp = kzalloc(sizeof(*lgp), GFP_KERNEL);
if (lgp == NULL) {
- pnfs_layoutget_release(lo);
+ put_layout_hdr(ino);
return NULL;
}
lgp->args.minlength = NFS4_MAX_UINT64;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 3fd2bc3..ba3d3f7 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -202,7 +202,6 @@ void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *,
struct nfs_open_context *, struct list_head *);
void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *);
int pnfs_layout_process(struct nfs4_layoutget *lgp);
-void pnfs_layoutget_release(struct pnfs_layout_hdr *);
void pnfs_layoutreturn_release(struct pnfs_layout_hdr *,
struct pnfs_layout_range *range);
void pnfs_destroy_layout(struct nfs_inode *);
--
1.6.6