aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-06-18 10:45:00 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-06-22 14:15:03 -0400
commitaf90f707fa6d54dbb725c4b919c976cd23cd07f2 (patch)
treec213e59eaf06df375269a1471670dc5df201d849 /fs/nfsd/nfs4xdr.c
parenta0649b2d3fffb1cde8745568c767f3a55a3462bc (diff)
nfsd: take struct file setup fully into nfs4_preprocess_stateid_op
This patch changes nfs4_preprocess_stateid_op so it always returns a valid struct file if it has been asked for that. For that we now allocate a temporary struct file for special stateids, and check permissions if we got the file structure from the stateid. This ensures that all callers will get their handling of special stateids right, and avoids code duplication. There is a little wart in here because the read code needs to know if we allocated a file structure so that it can copy around the read-ahead parameters. In the long run we should probably aim to cache full file structures used with special stateids instead. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c19
1 files changed, 1 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5286206169bc..3b3b3fbd9319 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -33,7 +33,6 @@
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <linux/file.h>
37#include <linux/slab.h> 36#include <linux/slab.h>
38#include <linux/namei.h> 37#include <linux/namei.h>
39#include <linux/statfs.h> 38#include <linux/statfs.h>
@@ -3418,7 +3417,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3418 unsigned long maxcount; 3417 unsigned long maxcount;
3419 struct xdr_stream *xdr = &resp->xdr; 3418 struct xdr_stream *xdr = &resp->xdr;
3420 struct file *file = read->rd_filp; 3419 struct file *file = read->rd_filp;
3421 struct svc_fh *fhp = read->rd_fhp;
3422 int starting_len = xdr->buf->len; 3420 int starting_len = xdr->buf->len;
3423 struct raparms *ra = NULL; 3421 struct raparms *ra = NULL;
3424 __be32 *p; 3422 __be32 *p;
@@ -3442,20 +3440,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3442 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len)); 3440 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
3443 maxcount = min_t(unsigned long, maxcount, read->rd_length); 3441 maxcount = min_t(unsigned long, maxcount, read->rd_length);
3444 3442
3445 if (read->rd_filp) { 3443 if (read->rd_tmp_file)
3446 err = nfsd_permission(resp->rqstp, fhp->fh_export,
3447 fhp->fh_dentry,
3448 NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
3449 if (err)
3450 goto err_truncate;
3451 } else {
3452 err = nfsd_open(resp->rqstp, fhp, S_IFREG, NFSD_MAY_READ,
3453 &file);
3454 if (err)
3455 goto err_truncate;
3456
3457 ra = nfsd_init_raparms(file); 3444 ra = nfsd_init_raparms(file);
3458 }
3459 3445
3460 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) 3446 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
3461 err = nfsd4_encode_splice_read(resp, read, file, maxcount); 3447 err = nfsd4_encode_splice_read(resp, read, file, maxcount);
@@ -3464,10 +3450,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3464 3450
3465 if (ra) 3451 if (ra)
3466 nfsd_put_raparams(file, ra); 3452 nfsd_put_raparams(file, ra);
3467 if (!read->rd_filp)
3468 fput(file);
3469 3453
3470err_truncate:
3471 if (err) 3454 if (err)
3472 xdr_truncate_encode(xdr, starting_len); 3455 xdr_truncate_encode(xdr, starting_len);
3473 return err; 3456 return err;