|
@@ -45,6 +45,7 @@
|
|
|
#include <linux/param.h>
|
|
|
#include <linux/major.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/file.h>
|
|
|
|
|
|
#include <linux/sunrpc/svc.h>
|
|
|
#include <linux/nfsd/nfsd.h>
|
|
@@ -477,26 +478,27 @@ static inline int
|
|
|
nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
|
|
|
{
|
|
|
int status;
|
|
|
- struct file *filp = NULL;
|
|
|
|
|
|
/* no need to check permission - this will be done in nfsd_read() */
|
|
|
|
|
|
+ read->rd_filp = NULL;
|
|
|
if (read->rd_offset >= OFFSET_MAX)
|
|
|
return nfserr_inval;
|
|
|
|
|
|
nfs4_lock_state();
|
|
|
/* check stateid */
|
|
|
if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
|
|
|
- CHECK_FH | RD_STATE, &filp))) {
|
|
|
+ CHECK_FH | RD_STATE, &read->rd_filp))) {
|
|
|
dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
|
|
|
goto out;
|
|
|
}
|
|
|
+ if (read->rd_filp)
|
|
|
+ get_file(read->rd_filp);
|
|
|
status = nfs_ok;
|
|
|
out:
|
|
|
nfs4_unlock_state();
|
|
|
read->rd_rqstp = rqstp;
|
|
|
read->rd_fhp = current_fh;
|
|
|
- read->rd_filp = filp;
|
|
|
return status;
|
|
|
}
|
|
|
|
|
@@ -633,6 +635,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
|
|
|
dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
|
|
|
goto out;
|
|
|
}
|
|
|
+ if (filp)
|
|
|
+ get_file(filp);
|
|
|
nfs4_unlock_state();
|
|
|
|
|
|
write->wr_bytes_written = write->wr_buflen;
|
|
@@ -644,6 +648,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
|
|
|
status = nfsd_write(rqstp, current_fh, filp, write->wr_offset,
|
|
|
write->wr_vec, write->wr_vlen, write->wr_buflen,
|
|
|
&write->wr_how_written);
|
|
|
+ if (filp)
|
|
|
+ fput(filp);
|
|
|
|
|
|
if (status == nfserr_symlink)
|
|
|
status = nfserr_inval;
|
|
@@ -932,6 +938,9 @@ encode_op:
|
|
|
nfs4_put_stateowner(replay_owner);
|
|
|
replay_owner = NULL;
|
|
|
}
|
|
|
+ /* XXX Ugh, we need to get rid of this kind of special case: */
|
|
|
+ if (op->opnum == OP_READ && op->u.read.rd_filp)
|
|
|
+ fput(op->u.read.rd_filp);
|
|
|
}
|
|
|
|
|
|
out:
|