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 <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:

committed by
J. Bruce Fields

parent
3eb15f2828
commit
47057abde5
@@ -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
|
||||
|
Reference in New Issue
Block a user