mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
Merge branch 'for-4.1' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "A quiet cycle this time; this is basically entirely bugfixes. The few that aren't cc'd to stable are cleanup or seemed unlikely to affect anyone much" * 'for-4.1' of git://linux-nfs.org/~bfields/linux: uapi: Remove kernel internal declaration nfsd: fix nsfd startup race triggering BUG_ON nfsd: eliminate NFSD_DEBUG nfsd4: fix READ permission checking nfsd4: disallow SEEK with special stateids nfsd4: disallow ALLOCATE with special stateids nfsd: add NFSEXP_PNFS to the exflags array nfsd: Remove duplicate macro define for max sec label length nfsd: allow setting acls with unenforceable DENYs nfsd: NFSD_FAULT_INJECTION depends on DEBUG_FS nfsd: remove unused status arg to nfsd4_cleanup_open_state nfsd: remove bogus setting of status in nfsd4_process_open2 NFSD: Use correct reply size calculating function NFSD: Using path_equal() for checking two paths
This commit is contained in:
commit
860448cf76
@ -31,7 +31,7 @@
|
||||
static struct hlist_head nlm_files[FILE_NRHASH];
|
||||
static DEFINE_MUTEX(nlm_file_mutex);
|
||||
|
||||
#ifdef NFSD_DEBUG
|
||||
#ifdef CONFIG_SUNRPC_DEBUG
|
||||
static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
|
||||
{
|
||||
u32 *fhp = (u32*)f->data;
|
||||
|
@ -108,7 +108,7 @@ config NFSD_V4_SECURITY_LABEL
|
||||
|
||||
config NFSD_FAULT_INJECTION
|
||||
bool "NFS server manual fault injection"
|
||||
depends on NFSD_V4 && DEBUG_KERNEL
|
||||
depends on NFSD_V4 && DEBUG_KERNEL && DEBUG_FS
|
||||
help
|
||||
This option enables support for manually injecting faults
|
||||
into the NFS server. This is intended to be used for
|
||||
|
@ -691,8 +691,7 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b)
|
||||
struct svc_export *orig = container_of(a, struct svc_export, h);
|
||||
struct svc_export *new = container_of(b, struct svc_export, h);
|
||||
return orig->ex_client == new->ex_client &&
|
||||
orig->ex_path.dentry == new->ex_path.dentry &&
|
||||
orig->ex_path.mnt == new->ex_path.mnt;
|
||||
path_equal(&orig->ex_path, &new->ex_path);
|
||||
}
|
||||
|
||||
static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
|
||||
@ -1159,6 +1158,7 @@ static struct flags {
|
||||
{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
|
||||
{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
|
||||
{ NFSEXP_V4ROOT, {"v4root", ""}},
|
||||
{ NFSEXP_PNFS, {"pnfs", ""}},
|
||||
{ 0, {"", ""}}
|
||||
};
|
||||
|
||||
|
@ -499,43 +499,13 @@ static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_s
|
||||
state->mask.allow |= astate->allow;
|
||||
}
|
||||
|
||||
/*
|
||||
* Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
|
||||
* READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
|
||||
* to traditional read/write/execute permissions.
|
||||
*
|
||||
* It's problematic to reject acls that use certain mode bits, because it
|
||||
* places the burden on users to learn the rules about which bits one
|
||||
* particular server sets, without giving the user a lot of help--we return an
|
||||
* error that could mean any number of different things. To make matters
|
||||
* worse, the problematic bits might be introduced by some application that's
|
||||
* automatically mapping from some other acl model.
|
||||
*
|
||||
* So wherever possible we accept anything, possibly erring on the side of
|
||||
* denying more permissions than necessary.
|
||||
*
|
||||
* However we do reject *explicit* DENY's of a few bits representing
|
||||
* permissions we could never deny:
|
||||
*/
|
||||
|
||||
static inline int check_deny(u32 mask, int isowner)
|
||||
{
|
||||
if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
|
||||
return -EINVAL;
|
||||
if (!isowner)
|
||||
return 0;
|
||||
if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct posix_acl *
|
||||
posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
||||
{
|
||||
struct posix_acl_entry *pace;
|
||||
struct posix_acl *pacl;
|
||||
int nace;
|
||||
int i, error = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* ACLs with no ACEs are treated differently in the inheritable
|
||||
@ -560,17 +530,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
||||
|
||||
pace = pacl->a_entries;
|
||||
pace->e_tag = ACL_USER_OBJ;
|
||||
error = check_deny(state->owner.deny, 1);
|
||||
if (error)
|
||||
goto out_err;
|
||||
low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
|
||||
|
||||
for (i=0; i < state->users->n; i++) {
|
||||
pace++;
|
||||
pace->e_tag = ACL_USER;
|
||||
error = check_deny(state->users->aces[i].perms.deny, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
low_mode_from_nfs4(state->users->aces[i].perms.allow,
|
||||
&pace->e_perm, flags);
|
||||
pace->e_uid = state->users->aces[i].uid;
|
||||
@ -579,18 +543,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
||||
|
||||
pace++;
|
||||
pace->e_tag = ACL_GROUP_OBJ;
|
||||
error = check_deny(state->group.deny, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
|
||||
add_to_mask(state, &state->group);
|
||||
|
||||
for (i=0; i < state->groups->n; i++) {
|
||||
pace++;
|
||||
pace->e_tag = ACL_GROUP;
|
||||
error = check_deny(state->groups->aces[i].perms.deny, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
low_mode_from_nfs4(state->groups->aces[i].perms.allow,
|
||||
&pace->e_perm, flags);
|
||||
pace->e_gid = state->groups->aces[i].gid;
|
||||
@ -605,15 +563,9 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
||||
|
||||
pace++;
|
||||
pace->e_tag = ACL_OTHER;
|
||||
error = check_deny(state->other.deny, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
|
||||
|
||||
return pacl;
|
||||
out_err:
|
||||
posix_acl_release(pacl);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
|
||||
|
@ -470,7 +470,7 @@ out:
|
||||
fh_put(resfh);
|
||||
kfree(resfh);
|
||||
}
|
||||
nfsd4_cleanup_open_state(cstate, open, status);
|
||||
nfsd4_cleanup_open_state(cstate, open);
|
||||
nfsd4_bump_seqid(cstate, status);
|
||||
return status;
|
||||
}
|
||||
@ -1030,6 +1030,8 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
|
||||
return status;
|
||||
}
|
||||
if (!file)
|
||||
return nfserr_bad_stateid;
|
||||
|
||||
status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
|
||||
fallocate->falloc_offset,
|
||||
@ -1069,6 +1071,8 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
|
||||
return status;
|
||||
}
|
||||
if (!file)
|
||||
return nfserr_bad_stateid;
|
||||
|
||||
switch (seek->seek_whence) {
|
||||
case NFS4_CONTENT_DATA:
|
||||
@ -1815,7 +1819,7 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
|
||||
bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
|
||||
}
|
||||
if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
|
||||
ret += NFSD4_MAX_SEC_LABEL_LEN + 12;
|
||||
ret += NFS4_MAXLABELLEN + 12;
|
||||
bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
|
||||
}
|
||||
/*
|
||||
@ -2282,13 +2286,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
|
||||
.op_func = (nfsd4op_func)nfsd4_allocate,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_name = "OP_ALLOCATE",
|
||||
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
|
||||
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
|
||||
},
|
||||
[OP_DEALLOCATE] = {
|
||||
.op_func = (nfsd4op_func)nfsd4_deallocate,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_name = "OP_DEALLOCATE",
|
||||
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
|
||||
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
|
||||
},
|
||||
[OP_SEEK] = {
|
||||
.op_func = (nfsd4op_func)nfsd4_seek,
|
||||
|
@ -1139,7 +1139,7 @@ hash_sessionid(struct nfs4_sessionid *sessionid)
|
||||
return sid->sequence % SESSION_HASH_SIZE;
|
||||
}
|
||||
|
||||
#ifdef NFSD_DEBUG
|
||||
#ifdef CONFIG_SUNRPC_DEBUG
|
||||
static inline void
|
||||
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
|
||||
{
|
||||
@ -4049,7 +4049,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
status = nfserr_bad_stateid;
|
||||
if (nfsd4_is_deleg_cur(open))
|
||||
goto out;
|
||||
status = nfserr_jukebox;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4118,7 +4117,7 @@ out:
|
||||
}
|
||||
|
||||
void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
|
||||
struct nfsd4_open *open, __be32 status)
|
||||
struct nfsd4_open *open)
|
||||
{
|
||||
if (open->op_openowner) {
|
||||
struct nfs4_stateowner *so = &open->op_openowner->oo_owner;
|
||||
|
@ -424,7 +424,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
||||
len += 4;
|
||||
dummy32 = be32_to_cpup(p++);
|
||||
READ_BUF(dummy32);
|
||||
if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN)
|
||||
if (dummy32 > NFS4_MAXLABELLEN)
|
||||
return nfserr_badlabel;
|
||||
len += (XDR_QUADLEN(dummy32) << 2);
|
||||
READMEM(buf, dummy32);
|
||||
@ -2020,7 +2020,7 @@ static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
|
||||
* dentries/path components in an array.
|
||||
*/
|
||||
for (;;) {
|
||||
if (cur.dentry == root->dentry && cur.mnt == root->mnt)
|
||||
if (path_equal(&cur, root))
|
||||
break;
|
||||
if (cur.dentry == cur.mnt->mnt_root) {
|
||||
if (follow_up(&cur))
|
||||
@ -3422,6 +3422,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
unsigned long maxcount;
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
struct file *file = read->rd_filp;
|
||||
struct svc_fh *fhp = read->rd_fhp;
|
||||
int starting_len = xdr->buf->len;
|
||||
struct raparms *ra;
|
||||
__be32 *p;
|
||||
@ -3445,12 +3446,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||
maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
|
||||
maxcount = min_t(unsigned long, maxcount, read->rd_length);
|
||||
|
||||
if (!read->rd_filp) {
|
||||
if (read->rd_filp)
|
||||
err = nfsd_permission(resp->rqstp, fhp->fh_export,
|
||||
fhp->fh_dentry,
|
||||
NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
|
||||
else
|
||||
err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
|
||||
&file, &ra);
|
||||
if (err)
|
||||
goto err_truncate;
|
||||
}
|
||||
if (err)
|
||||
goto err_truncate;
|
||||
|
||||
if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
|
||||
err = nfsd4_encode_splice_read(resp, read, file, maxcount);
|
||||
|
@ -1250,15 +1250,15 @@ static int __init init_nfsd(void)
|
||||
int retval;
|
||||
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
|
||||
|
||||
retval = register_cld_notifier();
|
||||
if (retval)
|
||||
return retval;
|
||||
retval = register_pernet_subsys(&nfsd_net_ops);
|
||||
if (retval < 0)
|
||||
goto out_unregister_notifier;
|
||||
retval = nfsd4_init_slabs();
|
||||
return retval;
|
||||
retval = register_cld_notifier();
|
||||
if (retval)
|
||||
goto out_unregister_pernet;
|
||||
retval = nfsd4_init_slabs();
|
||||
if (retval)
|
||||
goto out_unregister_notifier;
|
||||
retval = nfsd4_init_pnfs();
|
||||
if (retval)
|
||||
goto out_free_slabs;
|
||||
@ -1290,10 +1290,10 @@ out_exit_pnfs:
|
||||
nfsd4_exit_pnfs();
|
||||
out_free_slabs:
|
||||
nfsd4_free_slabs();
|
||||
out_unregister_pernet:
|
||||
unregister_pernet_subsys(&nfsd_net_ops);
|
||||
out_unregister_notifier:
|
||||
unregister_cld_notifier();
|
||||
out_unregister_pernet:
|
||||
unregister_pernet_subsys(&nfsd_net_ops);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1308,8 +1308,8 @@ static void __exit exit_nfsd(void)
|
||||
nfsd4_exit_pnfs();
|
||||
nfsd_fault_inject_cleanup();
|
||||
unregister_filesystem(&nfsd_fs_type);
|
||||
unregister_pernet_subsys(&nfsd_net_ops);
|
||||
unregister_cld_notifier();
|
||||
unregister_pernet_subsys(&nfsd_net_ops);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "export.h"
|
||||
|
||||
#undef ifdebug
|
||||
#ifdef NFSD_DEBUG
|
||||
#ifdef CONFIG_SUNRPC_DEBUG
|
||||
# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
|
||||
#else
|
||||
# define ifdebug(flag) if (0)
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "state.h"
|
||||
#include "nfsd.h"
|
||||
|
||||
#define NFSD4_MAX_SEC_LABEL_LEN 2048
|
||||
#define NFSD4_MAX_TAGLEN 128
|
||||
#define XDR_LEN(n) (((n) + 3) & ~3)
|
||||
|
||||
@ -683,7 +682,7 @@ extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
|
||||
struct svc_fh *current_fh, struct nfsd4_open *open);
|
||||
extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
|
||||
extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
|
||||
struct nfsd4_open *open, __be32 status);
|
||||
struct nfsd4_open *open);
|
||||
extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
|
||||
extern __be32 nfsd4_close(struct svc_rqst *rqstp,
|
||||
|
@ -16,6 +16,13 @@
|
||||
#include <linux/uidgid.h>
|
||||
#include <uapi/linux/nfs4.h>
|
||||
|
||||
enum nfs4_acl_whotype {
|
||||
NFS4_ACL_WHO_NAMED = 0,
|
||||
NFS4_ACL_WHO_OWNER,
|
||||
NFS4_ACL_WHO_GROUP,
|
||||
NFS4_ACL_WHO_EVERYONE,
|
||||
};
|
||||
|
||||
struct nfs4_ace {
|
||||
uint32_t type;
|
||||
uint32_t flag;
|
||||
|
@ -162,13 +162,6 @@
|
||||
*/
|
||||
#define NFS4_MAX_BACK_CHANNEL_OPS 2
|
||||
|
||||
enum nfs4_acl_whotype {
|
||||
NFS4_ACL_WHO_NAMED = 0,
|
||||
NFS4_ACL_WHO_OWNER,
|
||||
NFS4_ACL_WHO_GROUP,
|
||||
NFS4_ACL_WHO_EVERYONE,
|
||||
};
|
||||
|
||||
#endif /* _UAPI_LINUX_NFS4_H */
|
||||
|
||||
/*
|
||||
|
@ -11,14 +11,6 @@
|
||||
|
||||
#include <linux/sunrpc/debug.h>
|
||||
|
||||
/*
|
||||
* Enable debugging for nfsd.
|
||||
* Requires RPC_DEBUG.
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define NFSD_DEBUG 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* knfsd debug flags
|
||||
*/
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
/*
|
||||
* Export flags.
|
||||
*
|
||||
* Please update the expflags[] array in fs/nfsd/export.c when adding
|
||||
* a new flag.
|
||||
*/
|
||||
#define NFSEXP_READONLY 0x0001
|
||||
#define NFSEXP_INSECURE_PORT 0x0002
|
||||
|
Loading…
Reference in New Issue
Block a user