linux/fs/afs/xattr.c
<<
>>
Prefs
   1/* Extended attribute handling for AFS.  We use xattrs to get and set metadata
   2 * instead of providing pioctl().
   3 *
   4 * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public Licence
   9 * as published by the Free Software Foundation; either version
  10 * 2 of the Licence, or (at your option) any later version.
  11 */
  12
  13#include <linux/slab.h>
  14#include <linux/fs.h>
  15#include <linux/xattr.h>
  16#include "internal.h"
  17
  18static const char afs_xattr_list[] =
  19        "afs.cell\0"
  20        "afs.fid\0"
  21        "afs.volume";
  22
  23/*
  24 * Retrieve a list of the supported xattrs.
  25 */
  26ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size)
  27{
  28        if (size == 0)
  29                return sizeof(afs_xattr_list);
  30        if (size < sizeof(afs_xattr_list))
  31                return -ERANGE;
  32        memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list));
  33        return sizeof(afs_xattr_list);
  34}
  35
  36/*
  37 * Get the name of the cell on which a file resides.
  38 */
  39static int afs_xattr_get_cell(const struct xattr_handler *handler,
  40                              struct dentry *dentry,
  41                              struct inode *inode, const char *name,
  42                              void *buffer, size_t size)
  43{
  44        struct afs_vnode *vnode = AFS_FS_I(inode);
  45        struct afs_cell *cell = vnode->volume->cell;
  46        size_t namelen;
  47
  48        namelen = cell->name_len;
  49        if (size == 0)
  50                return namelen;
  51        if (namelen > size)
  52                return -ERANGE;
  53        memcpy(buffer, cell->name, size);
  54        return namelen;
  55}
  56
  57static const struct xattr_handler afs_xattr_afs_cell_handler = {
  58        .name   = "afs.cell",
  59        .get    = afs_xattr_get_cell,
  60};
  61
  62/*
  63 * Get the volume ID, vnode ID and vnode uniquifier of a file as a sequence of
  64 * hex numbers separated by colons.
  65 */
  66static int afs_xattr_get_fid(const struct xattr_handler *handler,
  67                             struct dentry *dentry,
  68                             struct inode *inode, const char *name,
  69                             void *buffer, size_t size)
  70{
  71        struct afs_vnode *vnode = AFS_FS_I(inode);
  72        char text[8 + 1 + 8 + 1 + 8 + 1];
  73        size_t len;
  74
  75        len = sprintf(text, "%x:%x:%x",
  76                      vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
  77        if (size == 0)
  78                return len;
  79        if (len > size)
  80                return -ERANGE;
  81        memcpy(buffer, text, len);
  82        return len;
  83}
  84
  85static const struct xattr_handler afs_xattr_afs_fid_handler = {
  86        .name   = "afs.fid",
  87        .get    = afs_xattr_get_fid,
  88};
  89
  90/*
  91 * Get the name of the volume on which a file resides.
  92 */
  93static int afs_xattr_get_volume(const struct xattr_handler *handler,
  94                              struct dentry *dentry,
  95                              struct inode *inode, const char *name,
  96                              void *buffer, size_t size)
  97{
  98        struct afs_vnode *vnode = AFS_FS_I(inode);
  99        const char *volname = vnode->volume->name;
 100        size_t namelen;
 101
 102        namelen = strlen(volname);
 103        if (size == 0)
 104                return namelen;
 105        if (namelen > size)
 106                return -ERANGE;
 107        memcpy(buffer, volname, size);
 108        return namelen;
 109}
 110
 111static const struct xattr_handler afs_xattr_afs_volume_handler = {
 112        .name   = "afs.volume",
 113        .get    = afs_xattr_get_volume,
 114};
 115
 116const struct xattr_handler *afs_xattr_handlers[] = {
 117        &afs_xattr_afs_cell_handler,
 118        &afs_xattr_afs_fid_handler,
 119        &afs_xattr_afs_volume_handler,
 120        NULL
 121};
 122