* NFSv4.2 mode_umask support @ 2016-12-03 3:53 J. Bruce Fields 2016-12-03 3:53 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 2016-12-09 20:59 ` NFSv4.2 mode_umask support J. Bruce Fields 0 siblings, 2 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-12-03 3:53 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker Cc: Andreas Gruenbacher, Linux NFS Mailing List Since the last version, just two minor changes: - client uses the stored supported attribute results instead of a new capability flag. - if a nutty client attempts to set both mode and new attribute, the server returns INVAL instead of ignoring the mode. Description, as before: The following patches allow the umask to be ignored in the presence of inheritable NFSv4 ACLs. Otherwise inheritable ACLs can be rendered mostly useless whenever the umask masks out group bits. This solves a problem we've seen complaints about for some time, both upstream and from RHEL users. The new protocol has been discussed in the IETF working group and is documented at: https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 It's unlikely that we'll discover problems requiring an incompatible change, so I think we should consider this for 4.10. --b. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] nfs: add support for the umask attribute 2016-12-03 3:53 NFSv4.2 mode_umask support J. Bruce Fields @ 2016-12-03 3:53 ` J. Bruce Fields 2016-12-03 3:53 ` [PATCH 2/2] nfsd: " J. Bruce Fields 2016-12-09 20:59 ` NFSv4.2 mode_umask support J. Bruce Fields 1 sibling, 1 reply; 14+ messages in thread From: J. Bruce Fields @ 2016-12-03 3:53 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker Cc: Andreas Gruenbacher, Linux NFS Mailing List From: Andreas Gruenbacher <agruenba@redhat.com> Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfs/dir.c | 7 ++++++- fs/nfs/nfs4proc.c | 16 ++++++++++++---- fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------ include/linux/nfs4.h | 1 + include/linux/nfs_xdr.h | 2 ++ 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f1af4cd1a33..837f12e683df 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1535,8 +1535,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, return -ENAMETOOLONG; if (open_flags & O_CREAT) { + struct nfs_server *server = NFS_SERVER(dir); + + if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) + mode &= ~current_umask(); + attr.ia_valid |= ATTR_MODE; - attr.ia_mode = mode & ~current_umask(); + attr.ia_mode = mode; } if (open_flags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7897826d7c51..df739778e4b3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1239,6 +1239,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.bitmask = nfs4_bitmask(server, label); p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; p->o_arg.label = nfs4_label_copy(p->a_label, label); + p->o_arg.umask = current_umask(); p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); switch (p->o_arg.claim) { case NFS4_OPEN_CLAIM_NULL: @@ -3277,7 +3278,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) -#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL) +#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_MODE_UMASK - 1UL) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) { @@ -3953,6 +3954,7 @@ static int nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_label l, *ilabel = NULL; struct nfs_open_context *ctx; struct nfs4_state *state; @@ -3964,7 +3966,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); if (IS_ERR(state)) { status = PTR_ERR(state); @@ -4172,6 +4175,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = nfs4_bitmask(server, data->label); + data->arg.umask = current_umask(); data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; @@ -4269,13 +4273,15 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mkdir(dir, dentry, sattr, label); trace_nfs4_mkdir(dir, &dentry->d_name, err); @@ -4378,13 +4384,15 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); trace_nfs4_mknod(dir, &dentry->d_name, err); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fc89e5ed07ee..b94706f0668b 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,7 @@ #include <linux/nfs.h> #include <linux/nfs4.h> #include <linux/nfs_fs.h> +#include <linux/fs_struct.h> #include "nfs4_fs.h" #include "internal.h" @@ -1003,7 +1004,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs4_label *label, const struct nfs_server *server, - bool excl_check) + bool excl_check, const umode_t *umask) { char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; @@ -1017,18 +1018,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, /* * We reserve enough space to write the entire attribute buffer at once. - * In the worst-case, this would be - * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) - * = 40 bytes, plus any contribution from variable-length fields - * such as owner/group. */ if (iap->ia_valid & ATTR_SIZE) { bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } + if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) + umask = NULL; if (iap->ia_valid & ATTR_MODE) { - bmval[1] |= FATTR4_WORD1_MODE; - len += 4; + if (umask) { + bmval[2] |= FATTR4_WORD2_MODE_UMASK; + len += 8; + } else { + bmval[1] |= FATTR4_WORD1_MODE; + len += 4; + } } if (iap->ia_valid & ATTR_UID) { owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); @@ -1129,6 +1133,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, *p++ = cpu_to_be32(label->len); p = xdr_encode_opaque_fixed(p, label->label, label->len); } + if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { + *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); + *p++ = cpu_to_be32(*umask); + } /* out: */ } @@ -1183,7 +1191,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * } encode_string(xdr, create->name->len, create->name->name); - encode_attrs(xdr, create->attrs, create->label, create->server, false); + encode_attrs(xdr, create->attrs, create->label, create->server, false, + &create->umask); } static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) @@ -1403,11 +1412,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op switch(arg->createmode) { case NFS4_CREATE_UNCHECKED: *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_GUARDED: *p = cpu_to_be32(NFS4_CREATE_GUARDED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_EXCLUSIVE: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); @@ -1416,7 +1427,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op case NFS4_CREATE_EXCLUSIVE4_1: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); encode_nfs4_verifier(xdr, &arg->u.verifier); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, + &arg->umask); } } @@ -1672,7 +1684,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); encode_nfs4_stateid(xdr, &arg->stateid); - encode_attrs(xdr, arg->iap, arg->label, server, false); + encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); } static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9094faf0699d..bca536341d1a 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -440,6 +440,7 @@ enum lock_type4 { #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) #define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13) #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) +#define FATTR4_WORD2_MODE_UMASK (1UL << 17) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index beb1e10f446e..ff82f42da656 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -418,6 +418,7 @@ struct nfs_openargs { enum open_claim_type4 claim; enum createmode4 createmode; const struct nfs4_label *label; + umode_t umask; }; struct nfs_openres { @@ -937,6 +938,7 @@ struct nfs4_create_arg { const struct nfs_fh * dir_fh; const u32 * bitmask; const struct nfs4_label *label; + umode_t umask; }; struct nfs4_create_res { -- 2.9.3 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/2] nfsd: add support for the umask attribute 2016-12-03 3:53 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields @ 2016-12-03 3:53 ` J. Bruce Fields 0 siblings, 0 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-12-03 3:53 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker Cc: Andreas Gruenbacher, Linux NFS Mailing List From: Andreas Gruenbacher <agruenba@redhat.com> Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfsd/nfs4proc.c | 3 +++ fs/nfsd/nfs4xdr.c | 26 +++++++++++++++++++++----- fs/nfsd/nfsd.h | 9 +++++++-- fs/nfsd/nfssvc.c | 4 ++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index e901cf124e9f..74a6e573e061 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -102,6 +102,9 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return nfserr_attrnotsupp; if (writable && !bmval_is_subset(bmval, writable)) return nfserr_inval; + if (writable && (bmval[2] & FATTR4_WORD2_MODE_UMASK) && + (bmval[1] & FATTR4_WORD1_MODE)) + return nfserr_inval; return nfs_ok; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 281739e1d477..79edde4577b2 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -33,6 +33,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <linux/fs_struct.h> #include <linux/file.h> #include <linux/slab.h> #include <linux/namei.h> @@ -299,7 +300,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct nfs4_acl **acl, - struct xdr_netobj *label) + struct xdr_netobj *label, int *umask) { int expected_len, len = 0; u32 dummy32; @@ -457,6 +458,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, return nfserr_jukebox; } #endif + if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { + if (!umask) + goto xdr_error; + READ_BUF(8); + len += 8; + dummy32 = be32_to_cpup(p++); + iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO); + dummy32 = be32_to_cpup(p++); + *umask = dummy32 & S_IRWXUGO; + iattr->ia_valid |= ATTR_MODE; + } if (len != expected_len) goto xdr_error; @@ -651,7 +663,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create return status; status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, - &create->cr_acl, &create->cr_label); + &create->cr_acl, &create->cr_label, + ¤t->fs->umask); if (status) goto out; @@ -896,13 +909,15 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) case NFS4_OPEN_NOCREATE: break; case NFS4_OPEN_CREATE: + current->fs->umask = 0; READ_BUF(4); open->op_createmode = be32_to_cpup(p++); switch (open->op_createmode) { case NFS4_CREATE_UNCHECKED: case NFS4_CREATE_GUARDED: status = nfsd4_decode_fattr(argp, open->op_bmval, - &open->op_iattr, &open->op_acl, &open->op_label); + &open->op_iattr, &open->op_acl, &open->op_label, + ¤t->fs->umask); if (status) goto out; break; @@ -916,7 +931,8 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) READ_BUF(NFS4_VERIFIER_SIZE); COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE); status = nfsd4_decode_fattr(argp, open->op_bmval, - &open->op_iattr, &open->op_acl, &open->op_label); + &open->op_iattr, &open->op_acl, &open->op_label, + ¤t->fs->umask); if (status) goto out; break; @@ -1153,7 +1169,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta if (status) return status; return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr, - &setattr->sa_acl, &setattr->sa_label); + &setattr->sa_acl, &setattr->sa_label, NULL); } static __be32 diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 7155239b2908..d74c8c44dc35 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -359,6 +359,7 @@ void nfsd_lockd_shutdown(void); #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ + FATTR4_WORD2_MODE_UMASK | \ NFSD4_2_SECURITY_ATTRS) extern u32 nfsd_suppattrs[3][3]; @@ -390,10 +391,14 @@ static inline bool nfsd_attrs_supported(u32 minorversion, u32 *bmval) (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL -#define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL +#define MAYBE_FATTR4_WORD2_SECURITY_LABEL \ + FATTR4_WORD2_SECURITY_LABEL #else -#define NFSD_WRITEABLE_ATTRS_WORD2 0 +#define MAYBE_FATTR4_WORD2_SECURITY_LABEL 0 #endif +#define NFSD_WRITEABLE_ATTRS_WORD2 \ + (FATTR4_WORD2_MODE_UMASK \ + | MAYBE_FATTR4_WORD2_SECURITY_LABEL) #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ NFSD_WRITEABLE_ATTRS_WORD0 diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index a2b65fc56dd6..e6bfd96734c0 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -661,8 +661,8 @@ nfsd(void *vrqstp) mutex_lock(&nfsd_mutex); /* At this point, the thread shares current->fs - * with the init process. We need to create files with a - * umask of 0 instead of init's umask. */ + * with the init process. We need to create files with the + * umask as defined by the client instead of init's umask. */ if (unshare_fs_struct() < 0) { printk("Unable to start nfsd thread: out of memory\n"); goto out; -- 2.9.3 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: NFSv4.2 mode_umask support 2016-12-03 3:53 NFSv4.2 mode_umask support J. Bruce Fields 2016-12-03 3:53 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields @ 2016-12-09 20:59 ` J. Bruce Fields 1 sibling, 0 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-12-09 20:59 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker Cc: Andreas Gruenbacher, Linux NFS Mailing List Ping--is there anything holding these up? --b. On Fri, Dec 02, 2016 at 10:53:02PM -0500, J. Bruce Fields wrote: > Since the last version, just two minor changes: > > - client uses the stored supported attribute results instead of > a new capability flag. > - if a nutty client attempts to set both mode and new attribute, > the server returns INVAL instead of ignoring the mode. > > Description, as before: > > The following patches allow the umask to be ignored in the presence of > inheritable NFSv4 ACLs. Otherwise inheritable ACLs can be rendered > mostly useless whenever the umask masks out group bits. > > This solves a problem we've seen complaints about for some time, both > upstream and from RHEL users. > > The new protocol has been discussed in the IETF working group and is > documented at: > > https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 > > It's unlikely that we'll discover problems requiring an incompatible > change, so I think we should consider this for 4.10. > > --b. ^ permalink raw reply [flat|nested] 14+ messages in thread
* NFSv4.2 mode_umask support @ 2016-11-23 20:41 J. Bruce Fields 2016-11-23 20:41 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 0 siblings, 1 reply; 14+ messages in thread From: J. Bruce Fields @ 2016-11-23 20:41 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs, Andreas Gruenbacher Resending--can we get any opinions on these? The following patches allow the umask to be ignored in the presence of inheritable NFSv4 ACLs. Otherwise inheritable ACLs can be rendered mostly useless whenever the umask masks out group bits. This solves a problem we've seen complaints about for some time, both upstream and from RHEL users. The new protocol has been discussed in the IETF working group and is documented at: https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 It's unlikely that we'll discover problems requiring an incompatible change, so I think we should consider this for 4.10. --b. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] nfs: add support for the umask attribute 2016-11-23 20:41 J. Bruce Fields @ 2016-11-23 20:41 ` J. Bruce Fields 2016-12-01 22:07 ` J. Bruce Fields 0 siblings, 1 reply; 14+ messages in thread From: J. Bruce Fields @ 2016-11-23 20:41 UTC (permalink / raw) To: Trond Myklebust, Anna Schumaker Cc: linux-nfs, Andreas Gruenbacher, J. Bruce Fields From: Andreas Gruenbacher <agruenba@redhat.com> Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfs/dir.c | 7 ++++++- fs/nfs/nfs4proc.c | 21 ++++++++++++++++----- fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------ include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 ++ 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f1af4cd1a33..0a8326bcb481 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1535,8 +1535,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, return -ENAMETOOLONG; if (open_flags & O_CREAT) { + struct nfs_server *server = NFS_SERVER(dir); + + if (!(server->caps & NFS_CAP_MODE_UMASK)) + mode &= ~current_umask(); + attr.ia_valid |= ATTR_MODE; - attr.ia_mode = mode & ~current_umask(); + attr.ia_mode = mode; } if (open_flags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7897826d7c51..1fa15fbf7b48 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1239,6 +1239,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.bitmask = nfs4_bitmask(server, label); p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; p->o_arg.label = nfs4_label_copy(p->a_label, label); + p->o_arg.umask = current_umask(); p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); switch (p->o_arg.claim) { case NFS4_OPEN_CLAIM_NULL: @@ -3277,7 +3278,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) -#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL) +#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_MODE_UMASK - 1UL) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) { @@ -3322,7 +3323,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| - NFS_CAP_SECURITY_LABEL); + NFS_CAP_SECURITY_LABEL| + NFS_CAP_MODE_UMASK); if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) server->caps |= NFS_CAP_ACLS; @@ -3350,6 +3352,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) server->caps |= NFS_CAP_SECURITY_LABEL; #endif + if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) + server->caps |= NFS_CAP_MODE_UMASK; memcpy(server->attr_bitmask_nl, res.attr_bitmask, sizeof(server->attr_bitmask)); server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -3953,6 +3957,7 @@ static int nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_label l, *ilabel = NULL; struct nfs_open_context *ctx; struct nfs4_state *state; @@ -3964,7 +3969,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); if (IS_ERR(state)) { status = PTR_ERR(state); @@ -4172,6 +4178,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = nfs4_bitmask(server, data->label); + data->arg.umask = current_umask(); data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; @@ -4269,13 +4276,15 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mkdir(dir, dentry, sattr, label); trace_nfs4_mkdir(dir, &dentry->d_name, err); @@ -4378,13 +4387,15 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); trace_nfs4_mknod(dir, &dentry->d_name, err); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fc89e5ed07ee..420d27865504 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,7 @@ #include <linux/nfs.h> #include <linux/nfs4.h> #include <linux/nfs_fs.h> +#include <linux/fs_struct.h> #include "nfs4_fs.h" #include "internal.h" @@ -1003,7 +1004,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs4_label *label, const struct nfs_server *server, - bool excl_check) + bool excl_check, const umode_t *umask) { char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; @@ -1017,18 +1018,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, /* * We reserve enough space to write the entire attribute buffer at once. - * In the worst-case, this would be - * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) - * = 40 bytes, plus any contribution from variable-length fields - * such as owner/group. */ if (iap->ia_valid & ATTR_SIZE) { bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } + if (!(server->caps & NFS_CAP_MODE_UMASK)) + umask = NULL; if (iap->ia_valid & ATTR_MODE) { - bmval[1] |= FATTR4_WORD1_MODE; - len += 4; + if (umask) { + bmval[2] |= FATTR4_WORD2_MODE_UMASK; + len += 8; + } else { + bmval[1] |= FATTR4_WORD1_MODE; + len += 4; + } } if (iap->ia_valid & ATTR_UID) { owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); @@ -1129,6 +1133,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, *p++ = cpu_to_be32(label->len); p = xdr_encode_opaque_fixed(p, label->label, label->len); } + if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { + *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); + *p++ = cpu_to_be32(*umask); + } /* out: */ } @@ -1183,7 +1191,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * } encode_string(xdr, create->name->len, create->name->name); - encode_attrs(xdr, create->attrs, create->label, create->server, false); + encode_attrs(xdr, create->attrs, create->label, create->server, false, + &create->umask); } static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) @@ -1403,11 +1412,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op switch(arg->createmode) { case NFS4_CREATE_UNCHECKED: *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_GUARDED: *p = cpu_to_be32(NFS4_CREATE_GUARDED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_EXCLUSIVE: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); @@ -1416,7 +1427,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op case NFS4_CREATE_EXCLUSIVE4_1: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); encode_nfs4_verifier(xdr, &arg->u.verifier); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, + &arg->umask); } } @@ -1672,7 +1684,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); encode_nfs4_stateid(xdr, &arg->stateid); - encode_attrs(xdr, arg->iap, arg->label, server, false); + encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); } static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9094faf0699d..bca536341d1a 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -440,6 +440,7 @@ enum lock_type4 { #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) #define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13) #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) +#define FATTR4_WORD2_MODE_UMASK (1UL << 17) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b34097c67848..87ab710772b3 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -250,5 +250,6 @@ struct nfs_server { #define NFS_CAP_LAYOUTSTATS (1U << 22) #define NFS_CAP_CLONE (1U << 23) #define NFS_CAP_COPY (1U << 24) +#define NFS_CAP_MODE_UMASK (1U << 25) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index beb1e10f446e..ff82f42da656 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -418,6 +418,7 @@ struct nfs_openargs { enum open_claim_type4 claim; enum createmode4 createmode; const struct nfs4_label *label; + umode_t umask; }; struct nfs_openres { @@ -937,6 +938,7 @@ struct nfs4_create_arg { const struct nfs_fh * dir_fh; const u32 * bitmask; const struct nfs4_label *label; + umode_t umask; }; struct nfs4_create_res { -- 2.9.3 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2016-11-23 20:41 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields @ 2016-12-01 22:07 ` J. Bruce Fields 2016-12-02 13:12 ` Andreas Gruenbacher 0 siblings, 1 reply; 14+ messages in thread From: J. Bruce Fields @ 2016-12-01 22:07 UTC (permalink / raw) To: J. Bruce Fields Cc: Trond Myklebust, Anna Schumaker, linux-nfs, Andreas Gruenbacher On Wed, Nov 23, 2016 at 03:41:39PM -0500, J. Bruce Fields wrote: > From: Andreas Gruenbacher <agruenba@redhat.com> > > Clients can set the umask attribute when creating files to cause the > server to apply it always except when inheriting permissions from the > parent directory. That way, the new files will end up with the same > permissions as files created locally. Trond asked out of band whether we could do away with the new server->caps bit and instead directly use the supported attribute bitmask (which is now also stored with the server). I haven't given this a real test yet, but it looks fine to me. If nobody sees an objection then I'll fold this into the client patch and resend. --b. diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 0a8326bcb481..32969907e218 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1537,7 +1537,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, if (open_flags & O_CREAT) { struct nfs_server *server = NFS_SERVER(dir); - if (!(server->caps & NFS_CAP_MODE_UMASK)) + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) mode &= ~current_umask(); attr.ia_valid |= ATTR_MODE; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1fa15fbf7b48..960ba55ddde7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3323,8 +3323,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| - NFS_CAP_SECURITY_LABEL| - NFS_CAP_MODE_UMASK); + NFS_CAP_SECURITY_LABEL); if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) server->caps |= NFS_CAP_ACLS; @@ -3352,8 +3351,6 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) server->caps |= NFS_CAP_SECURITY_LABEL; #endif - if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) - server->caps |= NFS_CAP_MODE_UMASK; memcpy(server->attr_bitmask_nl, res.attr_bitmask, sizeof(server->attr_bitmask)); server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -3969,7 +3966,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); - if (!(server->caps & NFS_CAP_MODE_UMASK)) + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); if (IS_ERR(state)) { @@ -4283,7 +4280,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, label = nfs4_label_init_security(dir, dentry, sattr, &l); - if (!(server->caps & NFS_CAP_MODE_UMASK)) + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mkdir(dir, dentry, sattr, label); @@ -4394,7 +4391,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, label = nfs4_label_init_security(dir, dentry, sattr, &l); - if (!(server->caps & NFS_CAP_MODE_UMASK)) + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 420d27865504..54714ce5dbd1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1023,7 +1023,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } - if (!(server->caps & NFS_CAP_MODE_UMASK)) + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) umask = NULL; if (iap->ia_valid & ATTR_MODE) { if (umask) { diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 87ab710772b3..b34097c67848 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -250,6 +250,5 @@ struct nfs_server { #define NFS_CAP_LAYOUTSTATS (1U << 22) #define NFS_CAP_CLONE (1U << 23) #define NFS_CAP_COPY (1U << 24) -#define NFS_CAP_MODE_UMASK (1U << 25) #endif ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2016-12-01 22:07 ` J. Bruce Fields @ 2016-12-02 13:12 ` Andreas Gruenbacher 2016-12-02 16:47 ` J. Bruce Fields 0 siblings, 1 reply; 14+ messages in thread From: Andreas Gruenbacher @ 2016-12-02 13:12 UTC (permalink / raw) To: J. Bruce Fields Cc: J. Bruce Fields, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List On Thu, Dec 1, 2016 at 11:07 PM, J. Bruce Fields <bfields@fieldses.org> wrote: > On Wed, Nov 23, 2016 at 03:41:39PM -0500, J. Bruce Fields wrote: >> From: Andreas Gruenbacher <agruenba@redhat.com> >> >> Clients can set the umask attribute when creating files to cause the >> server to apply it always except when inheriting permissions from the >> parent directory. That way, the new files will end up with the same >> permissions as files created locally. > > Trond asked out of band whether we could do away with the new > server->caps bit and instead directly use the supported attribute > bitmask (which is now also stored with the server). > > I haven't given this a real test yet, but it looks fine to me. > > If nobody sees an objection then I'll fold this into the client patch > and resend. Sure. I'm wondering why the code isn't checking for any other attributes like that. > --b. > > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c > index 0a8326bcb481..32969907e218 100644 > --- a/fs/nfs/dir.c > +++ b/fs/nfs/dir.c > @@ -1537,7 +1537,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, > if (open_flags & O_CREAT) { > struct nfs_server *server = NFS_SERVER(dir); > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) It seems that this patch should be checking in server->attr_bitmask, not server->attr_bitmask_nl. > mode &= ~current_umask(); > > attr.ia_valid |= ATTR_MODE; > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 1fa15fbf7b48..960ba55ddde7 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -3323,8 +3323,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| > NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| > NFS_CAP_CTIME|NFS_CAP_MTIME| > - NFS_CAP_SECURITY_LABEL| > - NFS_CAP_MODE_UMASK); > + NFS_CAP_SECURITY_LABEL); > if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && > res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) > server->caps |= NFS_CAP_ACLS; > @@ -3352,8 +3351,6 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) > server->caps |= NFS_CAP_SECURITY_LABEL; > #endif > - if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) > - server->caps |= NFS_CAP_MODE_UMASK; > memcpy(server->attr_bitmask_nl, res.attr_bitmask, > sizeof(server->attr_bitmask)); > server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; > @@ -3969,7 +3966,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, > > ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > sattr->ia_mode &= ~current_umask(); > state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); > if (IS_ERR(state)) { > @@ -4283,7 +4280,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, > > label = nfs4_label_init_security(dir, dentry, sattr, &l); > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > sattr->ia_mode &= ~current_umask(); > do { > err = _nfs4_proc_mkdir(dir, dentry, sattr, label); > @@ -4394,7 +4391,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, > > label = nfs4_label_init_security(dir, dentry, sattr, &l); > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > sattr->ia_mode &= ~current_umask(); > do { > err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c > index 420d27865504..54714ce5dbd1 100644 > --- a/fs/nfs/nfs4xdr.c > +++ b/fs/nfs/nfs4xdr.c > @@ -1023,7 +1023,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > bmval[0] |= FATTR4_WORD0_SIZE; > len += 8; > } > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > umask = NULL; > if (iap->ia_valid & ATTR_MODE) { > if (umask) { > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > index 87ab710772b3..b34097c67848 100644 > --- a/include/linux/nfs_fs_sb.h > +++ b/include/linux/nfs_fs_sb.h > @@ -250,6 +250,5 @@ struct nfs_server { > #define NFS_CAP_LAYOUTSTATS (1U << 22) > #define NFS_CAP_CLONE (1U << 23) > #define NFS_CAP_COPY (1U << 24) > -#define NFS_CAP_MODE_UMASK (1U << 25) > > #endif Thanks, Andreas ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2016-12-02 13:12 ` Andreas Gruenbacher @ 2016-12-02 16:47 ` J. Bruce Fields 2017-02-01 21:31 ` Olga Kornievskaia 2017-02-01 22:44 ` Andreas Gruenbacher 0 siblings, 2 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-12-02 16:47 UTC (permalink / raw) To: Andreas Gruenbacher Cc: J. Bruce Fields, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List On Fri, Dec 02, 2016 at 02:12:26PM +0100, Andreas Gruenbacher wrote: > On Thu, Dec 1, 2016 at 11:07 PM, J. Bruce Fields <bfields@fieldses.org> wrote: > > On Wed, Nov 23, 2016 at 03:41:39PM -0500, J. Bruce Fields wrote: > >> From: Andreas Gruenbacher <agruenba@redhat.com> > >> > >> Clients can set the umask attribute when creating files to cause the > >> server to apply it always except when inheriting permissions from the > >> parent directory. That way, the new files will end up with the same > >> permissions as files created locally. > > > > Trond asked out of band whether we could do away with the new > > server->caps bit and instead directly use the supported attribute > > bitmask (which is now also stored with the server). > > > > I haven't given this a real test yet, but it looks fine to me. > > > > If nobody sees an objection then I'll fold this into the client patch > > and resend. > > Sure. I'm wondering why the code isn't checking for any other > attributes like that. No idea. > > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c > > index 0a8326bcb481..32969907e218 100644 > > --- a/fs/nfs/dir.c > > +++ b/fs/nfs/dir.c > > @@ -1537,7 +1537,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, > > if (open_flags & O_CREAT) { > > struct nfs_server *server = NFS_SERVER(dir); > > > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > > It seems that this patch should be checking in server->attr_bitmask, > not server->attr_bitmask_nl. Huh, I missed that distinction. Looks like the results are the same, but, sure, attr_bitmask is probably better; fixed. Thanks for taking a look. --b. > > > mode &= ~current_umask(); > > > > attr.ia_valid |= ATTR_MODE; > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > > index 1fa15fbf7b48..960ba55ddde7 100644 > > --- a/fs/nfs/nfs4proc.c > > +++ b/fs/nfs/nfs4proc.c > > @@ -3323,8 +3323,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > > NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| > > NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| > > NFS_CAP_CTIME|NFS_CAP_MTIME| > > - NFS_CAP_SECURITY_LABEL| > > - NFS_CAP_MODE_UMASK); > > + NFS_CAP_SECURITY_LABEL); > > if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && > > res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) > > server->caps |= NFS_CAP_ACLS; > > @@ -3352,8 +3351,6 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > > if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) > > server->caps |= NFS_CAP_SECURITY_LABEL; > > #endif > > - if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) > > - server->caps |= NFS_CAP_MODE_UMASK; > > memcpy(server->attr_bitmask_nl, res.attr_bitmask, > > sizeof(server->attr_bitmask)); > > server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; > > @@ -3969,7 +3966,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, > > > > ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); > > > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > > sattr->ia_mode &= ~current_umask(); > > state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); > > if (IS_ERR(state)) { > > @@ -4283,7 +4280,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, > > > > label = nfs4_label_init_security(dir, dentry, sattr, &l); > > > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > > sattr->ia_mode &= ~current_umask(); > > do { > > err = _nfs4_proc_mkdir(dir, dentry, sattr, label); > > @@ -4394,7 +4391,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, > > > > label = nfs4_label_init_security(dir, dentry, sattr, &l); > > > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > > sattr->ia_mode &= ~current_umask(); > > do { > > err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); > > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c > > index 420d27865504..54714ce5dbd1 100644 > > --- a/fs/nfs/nfs4xdr.c > > +++ b/fs/nfs/nfs4xdr.c > > @@ -1023,7 +1023,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, > > bmval[0] |= FATTR4_WORD0_SIZE; > > len += 8; > > } > > - if (!(server->caps & NFS_CAP_MODE_UMASK)) > > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) > > umask = NULL; > > if (iap->ia_valid & ATTR_MODE) { > > if (umask) { > > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > > index 87ab710772b3..b34097c67848 100644 > > --- a/include/linux/nfs_fs_sb.h > > +++ b/include/linux/nfs_fs_sb.h > > @@ -250,6 +250,5 @@ struct nfs_server { > > #define NFS_CAP_LAYOUTSTATS (1U << 22) > > #define NFS_CAP_CLONE (1U << 23) > > #define NFS_CAP_COPY (1U << 24) > > -#define NFS_CAP_MODE_UMASK (1U << 25) > > > > #endif > > Thanks, > Andreas ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2016-12-02 16:47 ` J. Bruce Fields @ 2017-02-01 21:31 ` Olga Kornievskaia 2017-02-01 22:37 ` J. Bruce Fields 2017-02-01 22:44 ` Andreas Gruenbacher 1 sibling, 1 reply; 14+ messages in thread From: Olga Kornievskaia @ 2017-02-01 21:31 UTC (permalink / raw) To: J. Bruce Fields Cc: Andreas Gruenbacher, J. Bruce Fields, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List Any plans to add wireshark support for this? On Fri, Dec 2, 2016 at 11:47 AM, J. Bruce Fields <bfields@redhat.com> wrote: > On Fri, Dec 02, 2016 at 02:12:26PM +0100, Andreas Gruenbacher wrote: >> On Thu, Dec 1, 2016 at 11:07 PM, J. Bruce Fields <bfields@fieldses.org> wrote: >> > On Wed, Nov 23, 2016 at 03:41:39PM -0500, J. Bruce Fields wrote: >> >> From: Andreas Gruenbacher <agruenba@redhat.com> >> >> >> >> Clients can set the umask attribute when creating files to cause the >> >> server to apply it always except when inheriting permissions from the >> >> parent directory. That way, the new files will end up with the same >> >> permissions as files created locally. >> > >> > Trond asked out of band whether we could do away with the new >> > server->caps bit and instead directly use the supported attribute >> > bitmask (which is now also stored with the server). >> > >> > I haven't given this a real test yet, but it looks fine to me. >> > >> > If nobody sees an objection then I'll fold this into the client patch >> > and resend. >> >> Sure. I'm wondering why the code isn't checking for any other >> attributes like that. > > No idea. > >> > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c >> > index 0a8326bcb481..32969907e218 100644 >> > --- a/fs/nfs/dir.c >> > +++ b/fs/nfs/dir.c >> > @@ -1537,7 +1537,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, >> > if (open_flags & O_CREAT) { >> > struct nfs_server *server = NFS_SERVER(dir); >> > >> > - if (!(server->caps & NFS_CAP_MODE_UMASK)) >> > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) >> >> It seems that this patch should be checking in server->attr_bitmask, >> not server->attr_bitmask_nl. > > Huh, I missed that distinction. > > Looks like the results are the same, but, sure, attr_bitmask is probably > better; fixed. Thanks for taking a look. > > --b. > >> >> > mode &= ~current_umask(); >> > >> > attr.ia_valid |= ATTR_MODE; >> > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c >> > index 1fa15fbf7b48..960ba55ddde7 100644 >> > --- a/fs/nfs/nfs4proc.c >> > +++ b/fs/nfs/nfs4proc.c >> > @@ -3323,8 +3323,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f >> > NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| >> > NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| >> > NFS_CAP_CTIME|NFS_CAP_MTIME| >> > - NFS_CAP_SECURITY_LABEL| >> > - NFS_CAP_MODE_UMASK); >> > + NFS_CAP_SECURITY_LABEL); >> > if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && >> > res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) >> > server->caps |= NFS_CAP_ACLS; >> > @@ -3352,8 +3351,6 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f >> > if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) >> > server->caps |= NFS_CAP_SECURITY_LABEL; >> > #endif >> > - if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) >> > - server->caps |= NFS_CAP_MODE_UMASK; >> > memcpy(server->attr_bitmask_nl, res.attr_bitmask, >> > sizeof(server->attr_bitmask)); >> > server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; >> > @@ -3969,7 +3966,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, >> > >> > ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); >> > >> > - if (!(server->caps & NFS_CAP_MODE_UMASK)) >> > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) >> > sattr->ia_mode &= ~current_umask(); >> > state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); >> > if (IS_ERR(state)) { >> > @@ -4283,7 +4280,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, >> > >> > label = nfs4_label_init_security(dir, dentry, sattr, &l); >> > >> > - if (!(server->caps & NFS_CAP_MODE_UMASK)) >> > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) >> > sattr->ia_mode &= ~current_umask(); >> > do { >> > err = _nfs4_proc_mkdir(dir, dentry, sattr, label); >> > @@ -4394,7 +4391,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, >> > >> > label = nfs4_label_init_security(dir, dentry, sattr, &l); >> > >> > - if (!(server->caps & NFS_CAP_MODE_UMASK)) >> > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) >> > sattr->ia_mode &= ~current_umask(); >> > do { >> > err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); >> > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c >> > index 420d27865504..54714ce5dbd1 100644 >> > --- a/fs/nfs/nfs4xdr.c >> > +++ b/fs/nfs/nfs4xdr.c >> > @@ -1023,7 +1023,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, >> > bmval[0] |= FATTR4_WORD0_SIZE; >> > len += 8; >> > } >> > - if (!(server->caps & NFS_CAP_MODE_UMASK)) >> > + if (!(server->attr_bitmask_nl[2] & FATTR4_WORD2_MODE_UMASK)) >> > umask = NULL; >> > if (iap->ia_valid & ATTR_MODE) { >> > if (umask) { >> > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h >> > index 87ab710772b3..b34097c67848 100644 >> > --- a/include/linux/nfs_fs_sb.h >> > +++ b/include/linux/nfs_fs_sb.h >> > @@ -250,6 +250,5 @@ struct nfs_server { >> > #define NFS_CAP_LAYOUTSTATS (1U << 22) >> > #define NFS_CAP_CLONE (1U << 23) >> > #define NFS_CAP_COPY (1U << 24) >> > -#define NFS_CAP_MODE_UMASK (1U << 25) >> > >> > #endif >> >> Thanks, >> Andreas > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2017-02-01 21:31 ` Olga Kornievskaia @ 2017-02-01 22:37 ` J. Bruce Fields 0 siblings, 0 replies; 14+ messages in thread From: J. Bruce Fields @ 2017-02-01 22:37 UTC (permalink / raw) To: Olga Kornievskaia Cc: J. Bruce Fields, Andreas Gruenbacher, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List On Wed, Feb 01, 2017 at 04:31:25PM -0500, Olga Kornievskaia wrote: > Any plans to add wireshark support for this? Digging around, all I can find is this, which is outdated (it's for the umask not the umask+mode attribute), and never went upstream. I'll try to get back to this soon. (But if somebody else can fist, great.) --b. commit ed7c3053a99e Author: Andreas Gruenbacher <agruenba@redhat.com> Date: Thu Jan 14 21:20:38 2016 +0100 NFS: Add support for the proposed umask attribute Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. Change-Id: Id2a23c6839021107fdb32252be4a689b6125222c Signed-off-by: J. Bruce Fields <bfields@fieldses.org> diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c index 010db6e96761..bf458d4bccf4 100644 --- a/epan/dissectors/packet-nfs.c +++ b/epan/dissectors/packet-nfs.c @@ -420,6 +420,7 @@ static int hf_nfs4_fattr_layout_blksize = -1; static int hf_nfs4_fattr_security_label_lfs = -1; static int hf_nfs4_fattr_security_label_pi = -1; static int hf_nfs4_fattr_security_label_context = -1; +static int hf_nfs4_fattr_umask_mask = -1; static int hf_nfs4_who = -1; static int hf_nfs4_server = -1; static int hf_nfs4_fslocation = -1; @@ -6134,6 +6135,8 @@ static const value_string fattr4_names[] = { { FATTR4_CHANGE_ATTR_TYPE, "Change_Attr_Type" }, #define FATTR4_SECURITY_LABEL 80 { FATTR4_SECURITY_LABEL, "Security_Label" }, +#define FATTR4_UMASK 81 + { FATTR4_UMASK, "Umask" }, { 0, NULL } }; static value_string_ext fattr4_names_ext = VALUE_STRING_EXT_INIT(fattr4_names); @@ -6718,6 +6721,14 @@ dissect_nfs4_security_label(tvbuff_t *tvb, proto_tree *tree, int offset) return offset; } +static int +dissect_nfs4_umask(tvbuff_t *tvb, proto_tree *tree, int offset) +{ + offset = dissect_nfs4_mode(tvb, offset, tree); + offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_umask_mask, offset); + return offset; +} + #define FATTR4_BITMAP_ONLY 0 #define FATTR4_DISSECT_VALUES 1 @@ -7120,6 +7131,10 @@ dissect_nfs4_fattrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t offset = dissect_nfs4_security_label(tvb, attr_tree, offset); break; + case FATTR4_UMASK: + offset = dissect_nfs4_umask(tvb, attr_tree, offset); + break; + default: break; } @@ -12510,6 +12525,10 @@ proto_register_nfs(void) "label_format", "nfs.fattr4.security_label.lfs", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_nfs4_fattr_umask, { + "umask", "nfs.fattr4.umask", FT_UINT32, BASE_OCT, + NULL, 0, NULL, HFILL }}, + { &hf_nfs4_fattr_security_label_pi, { "policy_id", "nfs.fattr4.security_label.pi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2016-12-02 16:47 ` J. Bruce Fields 2017-02-01 21:31 ` Olga Kornievskaia @ 2017-02-01 22:44 ` Andreas Gruenbacher 2017-02-02 16:49 ` Olga Kornievskaia 1 sibling, 1 reply; 14+ messages in thread From: Andreas Gruenbacher @ 2017-02-01 22:44 UTC (permalink / raw) To: Olga Kornievskaia Cc: J. Bruce Fields, J. Bruce Fields, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List From: "J. Bruce Fields" <bfields@fieldses.org> On Wed, Feb 1, 2017 at 10:31 PM, Olga Kornievskaia <aglo@umich.edu> wrote: > Any plans to add wireshark support for this? We did, yes. Bruce had posted that together with the very first version. I couldn't find the wireshark patch for the current version of the proposal in the mailing list archive, so here's that. Andreas -- NFSv4.2 umask support --- epan/dissectors/packet-nfs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c index 6d1dd3b..5f2ce42 100644 --- a/epan/dissectors/packet-nfs.c +++ b/epan/dissectors/packet-nfs.c @@ -420,6 +420,7 @@ static int hf_nfs4_fattr_layout_blksize = -1; static int hf_nfs4_fattr_security_label_lfs = -1; static int hf_nfs4_fattr_security_label_pi = -1; static int hf_nfs4_fattr_security_label_context = -1; +static int hf_nfs4_fattr_umask_mask = -1; static int hf_nfs4_who = -1; static int hf_nfs4_server = -1; static int hf_nfs4_fslocation = -1; @@ -6133,6 +6134,8 @@ static const value_string fattr4_names[] = { { FATTR4_CHANGE_ATTR_TYPE, "Change_Attr_Type" }, #define FATTR4_SECURITY_LABEL 80 { FATTR4_SECURITY_LABEL, "Security_Label" }, +#define FATTR4_MODE_UMASK 81 + { FATTR4_MODE_UMASK, "Mode_Umask" }, { 0, NULL } }; static value_string_ext fattr4_names_ext = VALUE_STRING_EXT_INIT(fattr4_names); @@ -6717,6 +6720,14 @@ dissect_nfs4_security_label(tvbuff_t *tvb, proto_tree *tree, int offset) return offset; } +static int +dissect_nfs4_mode_umask(tvbuff_t *tvb, proto_tree *tree, int offset) +{ + offset = dissect_nfs4_mode(tvb, offset, tree); + offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_umask_mask, offset); + return offset; +} + #define FATTR4_BITMAP_ONLY 0 #define FATTR4_DISSECT_VALUES 1 @@ -7119,6 +7130,10 @@ dissect_nfs4_fattrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t offset = dissect_nfs4_security_label(tvb, attr_tree, offset); break; + case FATTR4_MODE_UMASK: + offset = dissect_nfs4_mode_umask(tvb, attr_tree, offset); + break; + default: break; } @@ -12509,6 +12524,10 @@ proto_register_nfs(void) "label_format", "nfs.fattr4.security_label.lfs", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_nfs4_fattr_umask_mask, { + "umask", "nfs.fattr4.umask", FT_UINT32, BASE_OCT, + NULL, 0, NULL, HFILL }}, + { &hf_nfs4_fattr_security_label_pi, { "policy_id", "nfs.fattr4.security_label.pi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] nfs: add support for the umask attribute 2017-02-01 22:44 ` Andreas Gruenbacher @ 2017-02-02 16:49 ` Olga Kornievskaia 0 siblings, 0 replies; 14+ messages in thread From: Olga Kornievskaia @ 2017-02-02 16:49 UTC (permalink / raw) To: Andreas Gruenbacher Cc: J. Bruce Fields, J. Bruce Fields, Trond Myklebust, Anna Schumaker, Linux NFS Mailing List On Wed, Feb 1, 2017 at 5:44 PM, Andreas Gruenbacher <agruenba@redhat.com> wrote: > From: "J. Bruce Fields" <bfields@fieldses.org> > > On Wed, Feb 1, 2017 at 10:31 PM, Olga Kornievskaia <aglo@umich.edu> wrote: >> Any plans to add wireshark support for this? > > We did, yes. Bruce had posted that together with the very first version. I > couldn't find the wireshark patch for the current version of the proposal in > the mailing list archive, so here's that. > > Andreas > > -- > > NFSv4.2 umask support > > --- > epan/dissectors/packet-nfs.c | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > > diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c > index 6d1dd3b..5f2ce42 100644 > --- a/epan/dissectors/packet-nfs.c > +++ b/epan/dissectors/packet-nfs.c > @@ -420,6 +420,7 @@ static int hf_nfs4_fattr_layout_blksize = -1; > static int hf_nfs4_fattr_security_label_lfs = -1; > static int hf_nfs4_fattr_security_label_pi = -1; > static int hf_nfs4_fattr_security_label_context = -1; > +static int hf_nfs4_fattr_umask_mask = -1; > static int hf_nfs4_who = -1; > static int hf_nfs4_server = -1; > static int hf_nfs4_fslocation = -1; > @@ -6133,6 +6134,8 @@ static const value_string fattr4_names[] = { > { FATTR4_CHANGE_ATTR_TYPE, "Change_Attr_Type" }, > #define FATTR4_SECURITY_LABEL 80 > { FATTR4_SECURITY_LABEL, "Security_Label" }, > +#define FATTR4_MODE_UMASK 81 > + { FATTR4_MODE_UMASK, "Mode_Umask" }, > { 0, NULL } > }; > static value_string_ext fattr4_names_ext = VALUE_STRING_EXT_INIT(fattr4_names); > @@ -6717,6 +6720,14 @@ dissect_nfs4_security_label(tvbuff_t *tvb, proto_tree *tree, int offset) > return offset; > } > > +static int > +dissect_nfs4_mode_umask(tvbuff_t *tvb, proto_tree *tree, int offset) > +{ > + offset = dissect_nfs4_mode(tvb, offset, tree); > + offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_umask_mask, offset); > + return offset; > +} > + > #define FATTR4_BITMAP_ONLY 0 > #define FATTR4_DISSECT_VALUES 1 > > @@ -7119,6 +7130,10 @@ dissect_nfs4_fattrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t > offset = dissect_nfs4_security_label(tvb, attr_tree, offset); > break; > > + case FATTR4_MODE_UMASK: > + offset = dissect_nfs4_mode_umask(tvb, attr_tree, offset); > + break; > + > default: > break; > } > @@ -12509,6 +12524,10 @@ proto_register_nfs(void) > "label_format", "nfs.fattr4.security_label.lfs", FT_UINT32, BASE_DEC, > NULL, 0, NULL, HFILL }}, > > + { &hf_nfs4_fattr_umask_mask, { > + "umask", "nfs.fattr4.umask", FT_UINT32, BASE_OCT, > + NULL, 0, NULL, HFILL }}, > + > { &hf_nfs4_fattr_security_label_pi, { > "policy_id", "nfs.fattr4.security_label.pi", FT_UINT32, BASE_DEC, > NULL, 0, NULL, HFILL }}, > -- > 2.7.4 Thank you Andreas. I have tried this patch and it decodes the OPEN compounds ok. Previously it's been garbage past the unknown attribute with value 81. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/2] NFSv4.2 mode_umask support
2016-10-28 20:23 ` [PATCH 0/2] NFSv4.2 umask support J. Bruce Fields
@ 2016-10-29 22:20 Andreas Gruenbacher
2016-10-28 20:23 ` [PATCH 0/2] NFSv4.2 umask support J. Bruce Fields
1 sibling, 1 reply; 14+ messages in thread
From: Andreas Gruenbacher @ 2016-10-29 22:20 UTC (permalink / raw)
To: linux-nfs
Cc: Andreas Gruenbacher, Trond Myklebust, Anna Schumaker,
J. Bruce Fields
Bruce and all,
On Fri, Oct 28, 2016 at 10:23 PM, J. Bruce Fields <bfields@redhat.com> wrote:
> From: "J. Bruce Fields" <bfields@redhat.com>
>
> The following patches allow the umask to be ignored in the presence of
> inheritable NFSv4 ACLs. Otherwise inheritable ACLs can be rendered
> mostly useless whenever the umask masks out group bits.
>
> This solves a problem we've seen complaints about for some time, both
> upstream and from RHEL users.
>
> The new protocol has been discussed in the IETF working group and is
> documented at:
>
> https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02
>
> It's unlikely that we'll discover problems requiring an incompatible
> change, so I think we should consider this for 4.10.
the patches still refer to the new attribute as FATTR4_WORD2_UMASK which is
confusing. Can we please call it FATTR4_WORD2_MODE_UMASK as in the patches in
this series to better match what the attribute is called in
draft-ietf-nfsv4-umask-02.
Other than refreshing the patches and renaming FATTR4_WORD2_UMASK to
FATTR4_WORD2_MODE_UMASK and NFS_CAP_UMASK to NFS_CAP_MODE_UMASK, the patches
here are the same.
Thanks,
Andreas
Andreas Gruenbacher (2):
nfs: add support for the umask attribute
nfsd: add support for the umask attribute
fs/nfs/dir.c | 7 ++++++-
fs/nfs/nfs4proc.c | 21 ++++++++++++++++-----
fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------
fs/nfsd/nfs4xdr.c | 26 +++++++++++++++++++++-----
fs/nfsd/nfsd.h | 9 +++++++--
fs/nfsd/nfssvc.c | 4 ++--
include/linux/nfs4.h | 1 +
include/linux/nfs_fs_sb.h | 1 +
include/linux/nfs_xdr.h | 2 ++
9 files changed, 80 insertions(+), 27 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/2] NFSv4.2 umask support @ 2016-10-28 20:23 ` J. Bruce Fields 2016-10-28 20:23 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 2016-10-29 22:20 ` Andreas Gruenbacher 0 siblings, 2 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-10-28 20:23 UTC (permalink / raw) To: linux-nfs Cc: Trond Myklebust, Anna Schumaker, Andreas Gruenbacher, J. Bruce Fields From: "J. Bruce Fields" <bfields@redhat.com> The following patches allow the umask to be ignored in the presence of inheritable NFSv4 ACLs. Otherwise inheritable ACLs can be rendered mostly useless whenever the umask masks out group bits. This solves a problem we've seen complaints about for some time, both upstream and from RHEL users. The new protocol has been discussed in the IETF working group and is documented at: https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 It's unlikely that we'll discover problems requiring an incompatible change, so I think we should consider this for 4.10. --b. Andreas Gruenbacher (2): nfs: add support for the umask attribute nfsd: add support for the umask attribute fs/nfs/dir.c | 7 ++++++- fs/nfs/nfs4proc.c | 21 ++++++++++++++++----- fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------ fs/nfsd/nfs4xdr.c | 26 +++++++++++++++++++++----- fs/nfsd/nfsd.h | 9 +++++++-- fs/nfsd/nfssvc.c | 4 ++-- include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 ++ 9 files changed, 80 insertions(+), 27 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] nfs: add support for the umask attribute 2016-10-28 20:23 ` [PATCH 0/2] NFSv4.2 umask support J. Bruce Fields @ 2016-10-28 20:23 ` J. Bruce Fields 2016-10-29 22:20 ` Andreas Gruenbacher 1 sibling, 0 replies; 14+ messages in thread From: J. Bruce Fields @ 2016-10-28 20:23 UTC (permalink / raw) To: linux-nfs Cc: Trond Myklebust, Anna Schumaker, Andreas Gruenbacher, J. Bruce Fields From: Andreas Gruenbacher <agruenba@redhat.com> Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfs/dir.c | 7 ++++++- fs/nfs/nfs4proc.c | 21 ++++++++++++++++----- fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------ include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 ++ 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f1af4cd1a33..eeb111e11972 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1535,8 +1535,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, return -ENAMETOOLONG; if (open_flags & O_CREAT) { + struct nfs_server *server = NFS_SERVER(dir); + + if (!(server->caps & NFS_CAP_UMASK)) + mode &= ~current_umask(); + attr.ia_valid |= ATTR_MODE; - attr.ia_mode = mode & ~current_umask(); + attr.ia_mode = mode; } if (open_flags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7897826d7c51..da08768e3cb3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1239,6 +1239,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.bitmask = nfs4_bitmask(server, label); p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; p->o_arg.label = nfs4_label_copy(p->a_label, label); + p->o_arg.umask = current_umask(); p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); switch (p->o_arg.claim) { case NFS4_OPEN_CLAIM_NULL: @@ -3277,7 +3278,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) -#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL) +#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_UMASK - 1UL) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) { @@ -3322,7 +3323,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| - NFS_CAP_SECURITY_LABEL); + NFS_CAP_SECURITY_LABEL| + NFS_CAP_UMASK); if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) server->caps |= NFS_CAP_ACLS; @@ -3350,6 +3352,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) server->caps |= NFS_CAP_SECURITY_LABEL; #endif + if (res.attr_bitmask[2] & FATTR4_WORD2_UMASK) + server->caps |= NFS_CAP_UMASK; memcpy(server->attr_bitmask_nl, res.attr_bitmask, sizeof(server->attr_bitmask)); server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -3953,6 +3957,7 @@ static int nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_label l, *ilabel = NULL; struct nfs_open_context *ctx; struct nfs4_state *state; @@ -3964,7 +3969,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_UMASK)) + sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); if (IS_ERR(state)) { status = PTR_ERR(state); @@ -4172,6 +4178,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = nfs4_bitmask(server, data->label); + data->arg.umask = current_umask(); data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; @@ -4269,13 +4276,15 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mkdir(dir, dentry, sattr, label); trace_nfs4_mkdir(dir, &dentry->d_name, err); @@ -4378,13 +4387,15 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); trace_nfs4_mknod(dir, &dentry->d_name, err); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fc89e5ed07ee..09c1b63c73e8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,7 @@ #include <linux/nfs.h> #include <linux/nfs4.h> #include <linux/nfs_fs.h> +#include <linux/fs_struct.h> #include "nfs4_fs.h" #include "internal.h" @@ -1003,7 +1004,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs4_label *label, const struct nfs_server *server, - bool excl_check) + bool excl_check, const umode_t *umask) { char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; @@ -1017,18 +1018,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, /* * We reserve enough space to write the entire attribute buffer at once. - * In the worst-case, this would be - * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) - * = 40 bytes, plus any contribution from variable-length fields - * such as owner/group. */ if (iap->ia_valid & ATTR_SIZE) { bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } + if (!(server->caps & NFS_CAP_UMASK)) + umask = NULL; if (iap->ia_valid & ATTR_MODE) { - bmval[1] |= FATTR4_WORD1_MODE; - len += 4; + if (umask) { + bmval[2] |= FATTR4_WORD2_UMASK; + len += 8; + } else { + bmval[1] |= FATTR4_WORD1_MODE; + len += 4; + } } if (iap->ia_valid & ATTR_UID) { owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); @@ -1129,6 +1133,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, *p++ = cpu_to_be32(label->len); p = xdr_encode_opaque_fixed(p, label->label, label->len); } + if (bmval[2] & FATTR4_WORD2_UMASK) { + *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); + *p++ = cpu_to_be32(*umask); + } /* out: */ } @@ -1183,7 +1191,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * } encode_string(xdr, create->name->len, create->name->name); - encode_attrs(xdr, create->attrs, create->label, create->server, false); + encode_attrs(xdr, create->attrs, create->label, create->server, false, + &create->umask); } static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) @@ -1403,11 +1412,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op switch(arg->createmode) { case NFS4_CREATE_UNCHECKED: *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_GUARDED: *p = cpu_to_be32(NFS4_CREATE_GUARDED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_EXCLUSIVE: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); @@ -1416,7 +1427,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op case NFS4_CREATE_EXCLUSIVE4_1: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); encode_nfs4_verifier(xdr, &arg->u.verifier); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, + &arg->umask); } } @@ -1672,7 +1684,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); encode_nfs4_stateid(xdr, &arg->stateid); - encode_attrs(xdr, arg->iap, arg->label, server, false); + encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); } static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9094faf0699d..2f0d37937afc 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -440,6 +440,7 @@ enum lock_type4 { #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) #define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13) #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) +#define FATTR4_WORD2_UMASK (1UL << 17) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b34097c67848..001625fae763 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -250,5 +250,6 @@ struct nfs_server { #define NFS_CAP_LAYOUTSTATS (1U << 22) #define NFS_CAP_CLONE (1U << 23) #define NFS_CAP_COPY (1U << 24) +#define NFS_CAP_UMASK (1U << 25) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index beb1e10f446e..ff82f42da656 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -418,6 +418,7 @@ struct nfs_openargs { enum open_claim_type4 claim; enum createmode4 createmode; const struct nfs4_label *label; + umode_t umask; }; struct nfs_openres { @@ -937,6 +938,7 @@ struct nfs4_create_arg { const struct nfs_fh * dir_fh; const u32 * bitmask; const struct nfs4_label *label; + umode_t umask; }; struct nfs4_create_res { -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/2] nfs: add support for the umask attribute 2016-10-28 20:23 ` [PATCH 0/2] NFSv4.2 umask support J. Bruce Fields 2016-10-28 20:23 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields @ 2016-10-29 22:20 ` Andreas Gruenbacher 1 sibling, 0 replies; 14+ messages in thread From: Andreas Gruenbacher @ 2016-10-29 22:20 UTC (permalink / raw) To: linux-nfs Cc: Andreas Gruenbacher, Trond Myklebust, Anna Schumaker, J. Bruce Fields Clients can set the umask attribute when creating files to cause the server to apply it always except when inheriting permissions from the parent directory. That way, the new files will end up with the same permissions as files created locally. See https://tools.ietf.org/html/draft-ietf-nfsv4-umask-02 for more details. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfs/dir.c | 7 ++++++- fs/nfs/nfs4proc.c | 21 ++++++++++++++++----- fs/nfs/nfs4xdr.c | 36 ++++++++++++++++++++++++------------ include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 ++ 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f1af4c..0a8326b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1535,8 +1535,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, return -ENAMETOOLONG; if (open_flags & O_CREAT) { + struct nfs_server *server = NFS_SERVER(dir); + + if (!(server->caps & NFS_CAP_MODE_UMASK)) + mode &= ~current_umask(); + attr.ia_valid |= ATTR_MODE; - attr.ia_mode = mode & ~current_umask(); + attr.ia_mode = mode; } if (open_flags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7897826..1fa15fb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1239,6 +1239,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.bitmask = nfs4_bitmask(server, label); p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; p->o_arg.label = nfs4_label_copy(p->a_label, label); + p->o_arg.umask = current_umask(); p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); switch (p->o_arg.claim) { case NFS4_OPEN_CLAIM_NULL: @@ -3277,7 +3278,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) -#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL) +#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_MODE_UMASK - 1UL) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) { @@ -3322,7 +3323,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| - NFS_CAP_SECURITY_LABEL); + NFS_CAP_SECURITY_LABEL| + NFS_CAP_MODE_UMASK); if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) server->caps |= NFS_CAP_ACLS; @@ -3350,6 +3352,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) server->caps |= NFS_CAP_SECURITY_LABEL; #endif + if (res.attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK) + server->caps |= NFS_CAP_MODE_UMASK; memcpy(server->attr_bitmask_nl, res.attr_bitmask, sizeof(server->attr_bitmask)); server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -3953,6 +3957,7 @@ static int nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_label l, *ilabel = NULL; struct nfs_open_context *ctx; struct nfs4_state *state; @@ -3964,7 +3969,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); if (IS_ERR(state)) { status = PTR_ERR(state); @@ -4172,6 +4178,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = nfs4_bitmask(server, data->label); + data->arg.umask = current_umask(); data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; @@ -4269,13 +4276,15 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mkdir(dir, dentry, sattr, label); trace_nfs4_mkdir(dir, &dentry->d_name, err); @@ -4378,13 +4387,15 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { + struct nfs_server *server = NFS_SERVER(dir); struct nfs4_exception exception = { }; struct nfs4_label l, *label = NULL; int err; label = nfs4_label_init_security(dir, dentry, sattr, &l); - sattr->ia_mode &= ~current_umask(); + if (!(server->caps & NFS_CAP_MODE_UMASK)) + sattr->ia_mode &= ~current_umask(); do { err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev); trace_nfs4_mknod(dir, &dentry->d_name, err); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fc89e5e..420d278 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,7 @@ #include <linux/nfs.h> #include <linux/nfs4.h> #include <linux/nfs_fs.h> +#include <linux/fs_struct.h> #include "nfs4_fs.h" #include "internal.h" @@ -1003,7 +1004,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs4_label *label, const struct nfs_server *server, - bool excl_check) + bool excl_check, const umode_t *umask) { char owner_name[IDMAP_NAMESZ]; char owner_group[IDMAP_NAMESZ]; @@ -1017,18 +1018,21 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, /* * We reserve enough space to write the entire attribute buffer at once. - * In the worst-case, this would be - * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) - * = 40 bytes, plus any contribution from variable-length fields - * such as owner/group. */ if (iap->ia_valid & ATTR_SIZE) { bmval[0] |= FATTR4_WORD0_SIZE; len += 8; } + if (!(server->caps & NFS_CAP_MODE_UMASK)) + umask = NULL; if (iap->ia_valid & ATTR_MODE) { - bmval[1] |= FATTR4_WORD1_MODE; - len += 4; + if (umask) { + bmval[2] |= FATTR4_WORD2_MODE_UMASK; + len += 8; + } else { + bmval[1] |= FATTR4_WORD1_MODE; + len += 4; + } } if (iap->ia_valid & ATTR_UID) { owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); @@ -1129,6 +1133,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, *p++ = cpu_to_be32(label->len); p = xdr_encode_opaque_fixed(p, label->label, label->len); } + if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { + *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); + *p++ = cpu_to_be32(*umask); + } /* out: */ } @@ -1183,7 +1191,8 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * } encode_string(xdr, create->name->len, create->name->name); - encode_attrs(xdr, create->attrs, create->label, create->server, false); + encode_attrs(xdr, create->attrs, create->label, create->server, false, + &create->umask); } static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) @@ -1403,11 +1412,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op switch(arg->createmode) { case NFS4_CREATE_UNCHECKED: *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_GUARDED: *p = cpu_to_be32(NFS4_CREATE_GUARDED); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, false, + &arg->umask); break; case NFS4_CREATE_EXCLUSIVE: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); @@ -1416,7 +1427,8 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op case NFS4_CREATE_EXCLUSIVE4_1: *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); encode_nfs4_verifier(xdr, &arg->u.verifier); - encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true); + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server, true, + &arg->umask); } } @@ -1672,7 +1684,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); encode_nfs4_stateid(xdr, &arg->stateid); - encode_attrs(xdr, arg->iap, arg->label, server, false); + encode_attrs(xdr, arg->iap, arg->label, server, false, NULL); } static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9094faf..bca5363 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -440,6 +440,7 @@ enum lock_type4 { #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) #define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13) #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) +#define FATTR4_WORD2_MODE_UMASK (1UL << 17) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b34097c..87ab710 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -250,5 +250,6 @@ struct nfs_server { #define NFS_CAP_LAYOUTSTATS (1U << 22) #define NFS_CAP_CLONE (1U << 23) #define NFS_CAP_COPY (1U << 24) +#define NFS_CAP_MODE_UMASK (1U << 25) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index beb1e10..ff82f42 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -418,6 +418,7 @@ struct nfs_openargs { enum open_claim_type4 claim; enum createmode4 createmode; const struct nfs4_label *label; + umode_t umask; }; struct nfs_openres { @@ -937,6 +938,7 @@ struct nfs4_create_arg { const struct nfs_fh * dir_fh; const u32 * bitmask; const struct nfs4_label *label; + umode_t umask; }; struct nfs4_create_res { -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-02-02 16:49 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-12-03 3:53 NFSv4.2 mode_umask support J. Bruce Fields 2016-12-03 3:53 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 2016-12-03 3:53 ` [PATCH 2/2] nfsd: " J. Bruce Fields 2016-12-09 20:59 ` NFSv4.2 mode_umask support J. Bruce Fields -- strict thread matches above, loose matches on Subject: below -- 2016-11-23 20:41 J. Bruce Fields 2016-11-23 20:41 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 2016-12-01 22:07 ` J. Bruce Fields 2016-12-02 13:12 ` Andreas Gruenbacher 2016-12-02 16:47 ` J. Bruce Fields 2017-02-01 21:31 ` Olga Kornievskaia 2017-02-01 22:37 ` J. Bruce Fields 2017-02-01 22:44 ` Andreas Gruenbacher 2017-02-02 16:49 ` Olga Kornievskaia 2016-10-29 22:20 [PATCH 0/2] NFSv4.2 mode_umask support Andreas Gruenbacher 2016-10-28 20:23 ` [PATCH 0/2] NFSv4.2 umask support J. Bruce Fields 2016-10-28 20:23 ` [PATCH 1/2] nfs: add support for the umask attribute J. Bruce Fields 2016-10-29 22:20 ` Andreas Gruenbacher
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).