Skip to content

Commit

Permalink
NFSv4.2: hook in the user extended attribute handlers
Browse files Browse the repository at this point in the history
Now that all the lower level code is there to make the RPC calls, hook
it in to the xattr handlers and the listxattr entry point, to make them
available.

Signed-off-by: Frank van der Linden <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
  • Loading branch information
fllinden authored and Trond Myklebust committed Jul 13, 2020
1 parent c10a751 commit 012a211
Showing 1 changed file with 121 additions and 2 deletions.
123 changes: 121 additions & 2 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "nfs4idmap.h"
#include "nfs4session.h"
#include "fscache.h"
#include "nfs42.h"

#include "nfs4trace.h"

Expand Down Expand Up @@ -7440,6 +7441,103 @@ nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)

#endif

#ifdef CONFIG_NFS_V4_2
static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
struct dentry *unused, struct inode *inode,
const char *key, const void *buf,
size_t buflen, int flags)
{
struct nfs_access_entry cache;

if (!nfs_server_capable(inode, NFS_CAP_XATTR))
return -EOPNOTSUPP;

/*
* There is no mapping from the MAY_* flags to the NFS_ACCESS_XA*
* flags right now. Handling of xattr operations use the normal
* file read/write permissions.
*
* Just in case the server has other ideas (which RFC 8276 allows),
* do a cached access check for the XA* flags to possibly avoid
* doing an RPC and getting EACCES back.
*/
if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
if (!(cache.mask & NFS_ACCESS_XAWRITE))
return -EACCES;
}

if (buf == NULL)
return nfs42_proc_removexattr(inode, key);
else
return nfs42_proc_setxattr(inode, key, buf, buflen, flags);
}

static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler,
struct dentry *unused, struct inode *inode,
const char *key, void *buf, size_t buflen)
{
struct nfs_access_entry cache;

if (!nfs_server_capable(inode, NFS_CAP_XATTR))
return -EOPNOTSUPP;

if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
if (!(cache.mask & NFS_ACCESS_XAREAD))
return -EACCES;
}

return nfs42_proc_getxattr(inode, key, buf, buflen);
}

static ssize_t
nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
{
u64 cookie;
bool eof;
int ret, size;
char *buf;
size_t buflen;
struct nfs_access_entry cache;

if (!nfs_server_capable(inode, NFS_CAP_XATTR))
return 0;

if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
if (!(cache.mask & NFS_ACCESS_XALIST))
return 0;
}

cookie = 0;
eof = false;
buflen = list_len ? list_len : XATTR_LIST_MAX;
buf = list_len ? list : NULL;
size = 0;

while (!eof) {
ret = nfs42_proc_listxattrs(inode, buf, buflen,
&cookie, &eof);
if (ret < 0)
return ret;

if (list_len) {
buf += ret;
buflen -= ret;
}
size += ret;
}

return size;
}

#else

static ssize_t
nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
{
return 0;
}
#endif /* CONFIG_NFS_V4_2 */

/*
* nfs_fhget will use either the mounted_on_fileid or the fileid
*/
Expand Down Expand Up @@ -10045,7 +10143,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {

static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
{
ssize_t error, error2;
ssize_t error, error2, error3;

error = generic_listxattr(dentry, list, size);
if (error < 0)
Expand All @@ -10058,7 +10156,17 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size);
if (error2 < 0)
return error2;
return error + error2;

if (list) {
list += error2;
size -= error2;
}

error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, size);
if (error3 < 0)
return error3;

return error + error2 + error3;
}

static const struct inode_operations nfs4_dir_inode_operations = {
Expand Down Expand Up @@ -10146,10 +10254,21 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
.set = nfs4_xattr_set_nfs4_acl,
};

#ifdef CONFIG_NFS_V4_2
static const struct xattr_handler nfs4_xattr_nfs4_user_handler = {
.prefix = XATTR_USER_PREFIX,
.get = nfs4_xattr_get_nfs4_user,
.set = nfs4_xattr_set_nfs4_user,
};
#endif

const struct xattr_handler *nfs4_xattr_handlers[] = {
&nfs4_xattr_nfs4_acl_handler,
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
&nfs4_xattr_nfs4_label_handler,
#endif
#ifdef CONFIG_NFS_V4_2
&nfs4_xattr_nfs4_user_handler,
#endif
NULL
};
Expand Down

0 comments on commit 012a211

Please sign in to comment.