Skip to content

Commit 47057ab

Browse files
Andreas GruenbacherJ. Bruce Fields
authored andcommitted
nfsd: add support for the 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. 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 <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 3eb15f2 commit 47057ab

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
102102
return nfserr_attrnotsupp;
103103
if (writable && !bmval_is_subset(bmval, writable))
104104
return nfserr_inval;
105+
if (writable && (bmval[2] & FATTR4_WORD2_MODE_UMASK) &&
106+
(bmval[1] & FATTR4_WORD1_MODE))
107+
return nfserr_inval;
105108
return nfs_ok;
106109
}
107110

fs/nfsd/nfs4xdr.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434
*/
3535

36+
#include <linux/fs_struct.h>
3637
#include <linux/file.h>
3738
#include <linux/slab.h>
3839
#include <linux/namei.h>
@@ -299,7 +300,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
299300
static __be32
300301
nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
301302
struct iattr *iattr, struct nfs4_acl **acl,
302-
struct xdr_netobj *label)
303+
struct xdr_netobj *label, int *umask)
303304
{
304305
int expected_len, len = 0;
305306
u32 dummy32;
@@ -457,6 +458,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
457458
return nfserr_jukebox;
458459
}
459460
#endif
461+
if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
462+
if (!umask)
463+
goto xdr_error;
464+
READ_BUF(8);
465+
len += 8;
466+
dummy32 = be32_to_cpup(p++);
467+
iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
468+
dummy32 = be32_to_cpup(p++);
469+
*umask = dummy32 & S_IRWXUGO;
470+
iattr->ia_valid |= ATTR_MODE;
471+
}
460472
if (len != expected_len)
461473
goto xdr_error;
462474

@@ -651,7 +663,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
651663
return status;
652664

653665
status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
654-
&create->cr_acl, &create->cr_label);
666+
&create->cr_acl, &create->cr_label,
667+
&current->fs->umask);
655668
if (status)
656669
goto out;
657670

@@ -896,13 +909,15 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
896909
case NFS4_OPEN_NOCREATE:
897910
break;
898911
case NFS4_OPEN_CREATE:
912+
current->fs->umask = 0;
899913
READ_BUF(4);
900914
open->op_createmode = be32_to_cpup(p++);
901915
switch (open->op_createmode) {
902916
case NFS4_CREATE_UNCHECKED:
903917
case NFS4_CREATE_GUARDED:
904918
status = nfsd4_decode_fattr(argp, open->op_bmval,
905-
&open->op_iattr, &open->op_acl, &open->op_label);
919+
&open->op_iattr, &open->op_acl, &open->op_label,
920+
&current->fs->umask);
906921
if (status)
907922
goto out;
908923
break;
@@ -916,7 +931,8 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
916931
READ_BUF(NFS4_VERIFIER_SIZE);
917932
COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
918933
status = nfsd4_decode_fattr(argp, open->op_bmval,
919-
&open->op_iattr, &open->op_acl, &open->op_label);
934+
&open->op_iattr, &open->op_acl, &open->op_label,
935+
&current->fs->umask);
920936
if (status)
921937
goto out;
922938
break;
@@ -1153,7 +1169,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
11531169
if (status)
11541170
return status;
11551171
return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
1156-
&setattr->sa_acl, &setattr->sa_label);
1172+
&setattr->sa_acl, &setattr->sa_label, NULL);
11571173
}
11581174

11591175
static __be32

fs/nfsd/nfsd.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ void nfsd_lockd_shutdown(void);
359359

360360
#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
361361
(NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
362+
FATTR4_WORD2_MODE_UMASK | \
362363
NFSD4_2_SECURITY_ATTRS)
363364

364365
extern u32 nfsd_suppattrs[3][3];
@@ -390,10 +391,14 @@ static inline bool nfsd_attrs_supported(u32 minorversion, u32 *bmval)
390391
(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
391392
| FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
392393
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
393-
#define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL
394+
#define MAYBE_FATTR4_WORD2_SECURITY_LABEL \
395+
FATTR4_WORD2_SECURITY_LABEL
394396
#else
395-
#define NFSD_WRITEABLE_ATTRS_WORD2 0
397+
#define MAYBE_FATTR4_WORD2_SECURITY_LABEL 0
396398
#endif
399+
#define NFSD_WRITEABLE_ATTRS_WORD2 \
400+
(FATTR4_WORD2_MODE_UMASK \
401+
| MAYBE_FATTR4_WORD2_SECURITY_LABEL)
397402

398403
#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
399404
NFSD_WRITEABLE_ATTRS_WORD0

fs/nfsd/nfssvc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,8 @@ nfsd(void *vrqstp)
661661
mutex_lock(&nfsd_mutex);
662662

663663
/* At this point, the thread shares current->fs
664-
* with the init process. We need to create files with a
665-
* umask of 0 instead of init's umask. */
664+
* with the init process. We need to create files with the
665+
* umask as defined by the client instead of init's umask. */
666666
if (unshare_fs_struct() < 0) {
667667
printk("Unable to start nfsd thread: out of memory\n");
668668
goto out;

include/linux/nfs4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ enum lock_type4 {
440440
#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4)
441441
#define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13)
442442
#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
443+
#define FATTR4_WORD2_MODE_UMASK (1UL << 17)
443444

444445
/* MDS threshold bitmap bits */
445446
#define THRESHOLD_RD (1UL << 0)

0 commit comments

Comments
 (0)