123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /* Extended attribute handling for AFS. We use xattrs to get and set metadata
- * instead of providing pioctl().
- *
- * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
- #include <linux/slab.h>
- #include <linux/fs.h>
- #include <linux/xattr.h>
- #include "internal.h"
- static const char afs_xattr_list[] =
- "afs.cell\0"
- "afs.fid\0"
- "afs.volume";
- /*
- * Retrieve a list of the supported xattrs.
- */
- ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size)
- {
- if (size == 0)
- return sizeof(afs_xattr_list);
- if (size < sizeof(afs_xattr_list))
- return -ERANGE;
- memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list));
- return sizeof(afs_xattr_list);
- }
- /*
- * Get the name of the cell on which a file resides.
- */
- static int afs_xattr_get_cell(const struct xattr_handler *handler,
- struct dentry *dentry,
- struct inode *inode, const char *name,
- void *buffer, size_t size)
- {
- struct afs_vnode *vnode = AFS_FS_I(inode);
- struct afs_cell *cell = vnode->volume->cell;
- size_t namelen;
- namelen = cell->name_len;
- if (size == 0)
- return namelen;
- if (namelen > size)
- return -ERANGE;
- memcpy(buffer, cell->name, namelen);
- return namelen;
- }
- static const struct xattr_handler afs_xattr_afs_cell_handler = {
- .name = "afs.cell",
- .get = afs_xattr_get_cell,
- };
- /*
- * Get the volume ID, vnode ID and vnode uniquifier of a file as a sequence of
- * hex numbers separated by colons.
- */
- static int afs_xattr_get_fid(const struct xattr_handler *handler,
- struct dentry *dentry,
- struct inode *inode, const char *name,
- void *buffer, size_t size)
- {
- struct afs_vnode *vnode = AFS_FS_I(inode);
- char text[8 + 1 + 8 + 1 + 8 + 1];
- size_t len;
- len = sprintf(text, "%x:%x:%x",
- vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
- if (size == 0)
- return len;
- if (len > size)
- return -ERANGE;
- memcpy(buffer, text, len);
- return len;
- }
- static const struct xattr_handler afs_xattr_afs_fid_handler = {
- .name = "afs.fid",
- .get = afs_xattr_get_fid,
- };
- /*
- * Get the name of the volume on which a file resides.
- */
- static int afs_xattr_get_volume(const struct xattr_handler *handler,
- struct dentry *dentry,
- struct inode *inode, const char *name,
- void *buffer, size_t size)
- {
- struct afs_vnode *vnode = AFS_FS_I(inode);
- const char *volname = vnode->volume->name;
- size_t namelen;
- namelen = strlen(volname);
- if (size == 0)
- return namelen;
- if (namelen > size)
- return -ERANGE;
- memcpy(buffer, volname, namelen);
- return namelen;
- }
- static const struct xattr_handler afs_xattr_afs_volume_handler = {
- .name = "afs.volume",
- .get = afs_xattr_get_volume,
- };
- const struct xattr_handler *afs_xattr_handlers[] = {
- &afs_xattr_afs_cell_handler,
- &afs_xattr_afs_fid_handler,
- &afs_xattr_afs_volume_handler,
- NULL
- };
|