[PATCH] nfsd4: fix open-create permissions
In the case where an open creates the file, we shouldn't be rechecking permissions to open the file; the open succeeds regardless of what the new file's mode bits say. This patch fixes the problem, but only by introducing yet another parameter to nfsd_create_v3. This is ugly. This will be fixed by later patches. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Acked-by: Neil Brown <neilb@suse.de> Cc: Jeff Garzik <jeff@garzik.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
af85852de0
commit
81ac95c556
|
@ -258,7 +258,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
|
|||
/* Now create the file and set attributes */
|
||||
nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
|
||||
attr, newfhp,
|
||||
argp->createmode, argp->verf, NULL);
|
||||
argp->createmode, argp->verf, NULL, NULL);
|
||||
|
||||
RETURN_STATUS(nfserr);
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
|
|||
{
|
||||
struct svc_fh resfh;
|
||||
__be32 status;
|
||||
int created = 0;
|
||||
|
||||
fh_init(&resfh, NFS4_FHSIZE);
|
||||
open->op_truncate = 0;
|
||||
|
@ -105,7 +106,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
|
|||
status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data,
|
||||
open->op_fname.len, &open->op_iattr,
|
||||
&resfh, open->op_createmode,
|
||||
(u32 *)open->op_verf.data, &open->op_truncate);
|
||||
(u32 *)open->op_verf.data, &open->op_truncate, &created);
|
||||
} else {
|
||||
status = nfsd_lookup(rqstp, current_fh,
|
||||
open->op_fname.data, open->op_fname.len, &resfh);
|
||||
|
@ -122,7 +123,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
|
|||
memcpy(open->op_stateowner->so_replay.rp_openfh,
|
||||
&resfh.fh_handle.fh_base, resfh.fh_handle.fh_size);
|
||||
|
||||
status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
|
||||
if (!created)
|
||||
status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
|
||||
|
||||
out:
|
||||
fh_put(&resfh);
|
||||
|
|
|
@ -1237,7 +1237,7 @@ __be32
|
|||
nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
char *fname, int flen, struct iattr *iap,
|
||||
struct svc_fh *resfhp, int createmode, u32 *verifier,
|
||||
int *truncp)
|
||||
int *truncp, int *created)
|
||||
{
|
||||
struct dentry *dentry, *dchild = NULL;
|
||||
struct inode *dirp;
|
||||
|
@ -1331,6 +1331,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
|
||||
if (host_err < 0)
|
||||
goto out_nfserr;
|
||||
if (created)
|
||||
*created = 1;
|
||||
|
||||
if (EX_ISSYNC(fhp->fh_export)) {
|
||||
err = nfserrno(nfsd_sync_dir(dentry));
|
||||
|
|
|
@ -89,7 +89,7 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
|
|||
__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
struct svc_fh *res, int createmode,
|
||||
u32 *verifier, int *truncp);
|
||||
u32 *verifier, int *truncp, int *created);
|
||||
__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t, unsigned long);
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
|
|
Loading…
Reference in New Issue