| From Trond.Myklebust@netapp.com Tue Dec 6 13:58:55 2011 |
| From: Trond Myklebust <Trond.Myklebust@netapp.com> |
| Date: Tue, 18 Oct 2011 10:11:07 -0700 |
| Subject: NFS: Prevent 3.0 from crashing if it receives a partial layout |
| To: stable@kernel.org |
| Cc: "Fred Isaman , Trond Myklebust" <iisaman@netapp.com> |
| Message-ID: <1318957867-19760-1-git-send-email-Trond.Myklebust@netapp.com> |
| |
| From: Trond Myklebust <Trond.Myklebust@netapp.com> |
| |
| This is a backport of critical parts of |
| commit 7c24d9489f "NFSv4.1: File layout only supports whole file layouts" |
| |
| It prevents the file layout driver from (incorrectly) using |
| partial layouts, but ignores the part of the referenced commmit that |
| relies on additional machinery to change the LAYOUTGET request |
| based on layout driver. |
| |
| Signed-off-by: Fred Isaman <iisaman@netapp.com> |
| Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/nfs/nfs4filelayout.c | 8 ++++++++ |
| fs/nfs/pnfs.c | 3 ++- |
| 2 files changed, 10 insertions(+), 1 deletion(-) |
| |
| --- a/fs/nfs/nfs4filelayout.c |
| +++ b/fs/nfs/nfs4filelayout.c |
| @@ -428,6 +428,14 @@ filelayout_check_layout(struct pnfs_layo |
| |
| dprintk("--> %s\n", __func__); |
| |
| + /* FIXME: remove this check when layout segment support is added */ |
| + if (lgr->range.offset != 0 || |
| + lgr->range.length != NFS4_MAX_UINT64) { |
| + dprintk("%s Only whole file layouts supported. Use MDS i/o\n", |
| + __func__); |
| + goto out; |
| + } |
| + |
| if (fl->pattern_offset > lgr->range.offset) { |
| dprintk("%s pattern_offset %lld too large\n", |
| __func__, fl->pattern_offset); |
| --- a/fs/nfs/pnfs.c |
| +++ b/fs/nfs/pnfs.c |
| @@ -980,7 +980,8 @@ pnfs_update_layout(struct inode *ino, |
| arg.offset -= pg_offset; |
| arg.length += pg_offset; |
| } |
| - arg.length = PAGE_CACHE_ALIGN(arg.length); |
| + if (arg.length != NFS4_MAX_UINT64) |
| + arg.length = PAGE_CACHE_ALIGN(arg.length); |
| |
| lseg = send_layoutget(lo, ctx, &arg, gfp_flags); |
| if (!lseg && first) { |