Skip to content

Commit d3e3b7e

Browse files
dhowellstorvalds
authored andcommitted
afs: Add metadata xattrs
Add xattrs to allow the user to get/set metadata in lieu of having pioctl() available. The following xattrs are now available: - "afs.cell" The name of the cell in which the vnode's volume resides. - "afs.fid" The volume ID, vnode ID and vnode uniquifier of the file as three hex numbers separated by colons. - "afs.volume" The name of the volume in which the vnode resides. For example: # getfattr -d -m ".*" /mnt/scratch getfattr: Removing leading '/' from absolute path names # file: mnt/scratch afs.cell="mycell.myorg.org" afs.fid="10000b:1:1" afs.volume="scratch" Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent fd24982 commit d3e3b7e

File tree

8 files changed

+138
-2
lines changed

8 files changed

+138
-2
lines changed

fs/afs/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ kafs-objs := \
2727
vlocation.o \
2828
vnode.o \
2929
volume.o \
30-
write.o
30+
write.o \
31+
xattr.o
3132

3233
obj-$(CONFIG_AFS_FS) := kafs.o

fs/afs/dir.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const struct inode_operations afs_dir_inode_operations = {
6161
.permission = afs_permission,
6262
.getattr = afs_getattr,
6363
.setattr = afs_setattr,
64+
.listxattr = afs_listxattr,
6465
};
6566

6667
const struct dentry_operations afs_fs_dentry_operations = {

fs/afs/file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const struct inode_operations afs_file_inode_operations = {
4646
.getattr = afs_getattr,
4747
.setattr = afs_setattr,
4848
.permission = afs_permission,
49+
.listxattr = afs_listxattr,
4950
};
5051

5152
const struct address_space_operations afs_fs_aops = {

fs/afs/inode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ struct afs_iget_data {
2828
struct afs_volume *volume; /* volume on which resides */
2929
};
3030

31+
static const struct inode_operations afs_symlink_inode_operations = {
32+
.get_link = page_get_link,
33+
.listxattr = afs_listxattr,
34+
};
35+
3136
/*
3237
* map the AFS file status to the inode member variables
3338
*/
@@ -67,7 +72,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
6772
inode->i_fop = &afs_mntpt_file_operations;
6873
} else {
6974
inode->i_mode = S_IFLNK | vnode->status.mode;
70-
inode->i_op = &page_symlink_inode_operations;
75+
inode->i_op = &afs_symlink_inode_operations;
7176
}
7277
inode_nohighmem(inode);
7378
break;

fs/afs/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,11 @@ extern int afs_writeback_all(struct afs_vnode *);
731731
extern int afs_flush(struct file *, fl_owner_t);
732732
extern int afs_fsync(struct file *, loff_t, loff_t, int);
733733

734+
/*
735+
* xattr.c
736+
*/
737+
extern const struct xattr_handler *afs_xattr_handlers[];
738+
extern ssize_t afs_listxattr(struct dentry *, char *, size_t);
734739

735740
/*****************************************************************************/
736741
/*

fs/afs/mntpt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const struct inode_operations afs_mntpt_inode_operations = {
3535
.lookup = afs_mntpt_lookup,
3636
.readlink = page_readlink,
3737
.getattr = afs_getattr,
38+
.listxattr = afs_listxattr,
3839
};
3940

4041
const struct inode_operations afs_autocell_inode_operations = {

fs/afs/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ static int afs_fill_super(struct super_block *sb,
319319
sb->s_blocksize_bits = PAGE_SHIFT;
320320
sb->s_magic = AFS_FS_MAGIC;
321321
sb->s_op = &afs_super_ops;
322+
sb->s_xattr = afs_xattr_handlers;
322323
ret = super_setup_bdi(sb);
323324
if (ret)
324325
return ret;

fs/afs/xattr.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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+
18+
static 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+
*/
26+
ssize_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+
*/
39+
static 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 = strlen(cell->name);
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+
57+
static 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+
*/
66+
static 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+
85+
static 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+
*/
93+
static 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->vlocation->vldb.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+
111+
static const struct xattr_handler afs_xattr_afs_volume_handler = {
112+
.name = "afs.volume",
113+
.get = afs_xattr_get_volume,
114+
};
115+
116+
const 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+
};

0 commit comments

Comments
 (0)