Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fs/9p: Add support user. xattr

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>

authored by

Aneesh Kumar K.V and committed by
Eric Van Hensbergen
ebf46264 eda25e46

+289 -3
+3 -1
fs/9p/Makefile
··· 8 8 vfs_dir.o \ 9 9 vfs_dentry.o \ 10 10 v9fs.o \ 11 - fid.o 11 + fid.o \ 12 + xattr.o \ 13 + xattr_user.o 12 14 13 15 9p-$(CONFIG_9P_FSCACHE) += cache.o
+15
fs/9p/vfs_inode.c
··· 35 35 #include <linux/idr.h> 36 36 #include <linux/sched.h> 37 37 #include <linux/slab.h> 38 + #include <linux/xattr.h> 38 39 #include <net/9p/9p.h> 39 40 #include <net/9p/client.h> 40 41 ··· 43 42 #include "v9fs_vfs.h" 44 43 #include "fid.h" 45 44 #include "cache.h" 45 + #include "xattr.h" 46 46 47 47 static const struct inode_operations v9fs_dir_inode_operations; 48 48 static const struct inode_operations v9fs_dir_inode_operations_dotu; ··· 1933 1931 .rename = v9fs_vfs_rename, 1934 1932 .getattr = v9fs_vfs_getattr_dotl, 1935 1933 .setattr = v9fs_vfs_setattr_dotl, 1934 + .setxattr = generic_setxattr, 1935 + .getxattr = generic_getxattr, 1936 + .removexattr = generic_removexattr, 1937 + .listxattr = v9fs_listxattr, 1938 + 1936 1939 }; 1937 1940 1938 1941 static const struct inode_operations v9fs_dir_inode_operations = { ··· 1960 1953 static const struct inode_operations v9fs_file_inode_operations_dotl = { 1961 1954 .getattr = v9fs_vfs_getattr_dotl, 1962 1955 .setattr = v9fs_vfs_setattr_dotl, 1956 + .setxattr = generic_setxattr, 1957 + .getxattr = generic_getxattr, 1958 + .removexattr = generic_removexattr, 1959 + .listxattr = v9fs_listxattr, 1963 1960 }; 1964 1961 1965 1962 static const struct inode_operations v9fs_symlink_inode_operations = { ··· 1980 1969 .put_link = v9fs_vfs_put_link, 1981 1970 .getattr = v9fs_vfs_getattr_dotl, 1982 1971 .setattr = v9fs_vfs_setattr_dotl, 1972 + .setxattr = generic_setxattr, 1973 + .getxattr = generic_getxattr, 1974 + .removexattr = generic_removexattr, 1975 + .listxattr = v9fs_listxattr, 1983 1976 };
+4 -2
fs/9p/vfs_super.c
··· 45 45 #include "v9fs.h" 46 46 #include "v9fs_vfs.h" 47 47 #include "fid.h" 48 + #include "xattr.h" 48 49 49 50 static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl; 50 51 ··· 78 77 sb->s_blocksize_bits = fls(v9ses->maxdata - 1); 79 78 sb->s_blocksize = 1 << sb->s_blocksize_bits; 80 79 sb->s_magic = V9FS_MAGIC; 81 - if (v9fs_proto_dotl(v9ses)) 80 + if (v9fs_proto_dotl(v9ses)) { 82 81 sb->s_op = &v9fs_super_ops_dotl; 83 - else 82 + sb->s_xattr = v9fs_xattr_handlers; 83 + } else 84 84 sb->s_op = &v9fs_super_ops; 85 85 sb->s_bdi = &v9ses->bdi; 86 86
+160
fs/9p/xattr.c
··· 1 + /* 2 + * Copyright IBM Corporation, 2010 3 + * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of version 2.1 of the GNU Lesser General Public License 7 + * as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it would be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 + * 13 + */ 14 + 15 + #include <linux/module.h> 16 + #include <linux/fs.h> 17 + #include <linux/sched.h> 18 + #include <net/9p/9p.h> 19 + #include <net/9p/client.h> 20 + 21 + #include "fid.h" 22 + #include "xattr.h" 23 + 24 + /* 25 + * v9fs_xattr_get() 26 + * 27 + * Copy an extended attribute into the buffer 28 + * provided, or compute the buffer size required. 29 + * Buffer is NULL to compute the size of the buffer required. 30 + * 31 + * Returns a negative error number on failure, or the number of bytes 32 + * used / required on success. 33 + */ 34 + ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name, 35 + void *buffer, size_t buffer_size) 36 + { 37 + ssize_t retval; 38 + int msize, read_count; 39 + u64 offset = 0, attr_size; 40 + struct p9_fid *fid, *attr_fid; 41 + 42 + P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu\n", 43 + __func__, name, buffer_size); 44 + 45 + fid = v9fs_fid_lookup(dentry); 46 + if (IS_ERR(fid)) 47 + return PTR_ERR(fid); 48 + 49 + attr_fid = p9_client_xattrwalk(fid, name, &attr_size); 50 + if (IS_ERR(attr_fid)) { 51 + retval = PTR_ERR(attr_fid); 52 + P9_DPRINTK(P9_DEBUG_VFS, 53 + "p9_client_attrwalk failed %zd\n", retval); 54 + attr_fid = NULL; 55 + goto error; 56 + } 57 + if (!buffer_size) { 58 + /* request to get the attr_size */ 59 + retval = attr_size; 60 + goto error; 61 + } 62 + if (attr_size > buffer_size) { 63 + retval = -ERANGE; 64 + goto error; 65 + } 66 + msize = attr_fid->clnt->msize; 67 + while (attr_size) { 68 + if (attr_size > (msize - P9_IOHDRSZ)) 69 + read_count = msize - P9_IOHDRSZ; 70 + else 71 + read_count = attr_size; 72 + read_count = p9_client_read(attr_fid, ((char *)buffer)+offset, 73 + 0, offset, read_count); 74 + if (read_count < 0) { 75 + /* error in xattr read */ 76 + retval = read_count; 77 + goto error; 78 + } 79 + offset += read_count; 80 + attr_size -= read_count; 81 + } 82 + /* Total read xattr bytes */ 83 + retval = offset; 84 + error: 85 + if (attr_fid) 86 + p9_client_clunk(attr_fid); 87 + return retval; 88 + 89 + } 90 + 91 + /* 92 + * v9fs_xattr_set() 93 + * 94 + * Create, replace or remove an extended attribute for this inode. Buffer 95 + * is NULL to remove an existing extended attribute, and non-NULL to 96 + * either replace an existing extended attribute, or create a new extended 97 + * attribute. The flags XATTR_REPLACE and XATTR_CREATE 98 + * specify that an extended attribute must exist and must not exist 99 + * previous to the call, respectively. 100 + * 101 + * Returns 0, or a negative error number on failure. 102 + */ 103 + int v9fs_xattr_set(struct dentry *dentry, const char *name, 104 + const void *value, size_t value_len, int flags) 105 + { 106 + u64 offset = 0; 107 + int retval, msize, write_count; 108 + struct p9_fid *fid = NULL; 109 + 110 + P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu flags = %d\n", 111 + __func__, name, value_len, flags); 112 + 113 + fid = v9fs_fid_clone(dentry); 114 + if (IS_ERR(fid)) { 115 + retval = PTR_ERR(fid); 116 + fid = NULL; 117 + goto error; 118 + } 119 + /* 120 + * On success fid points to xattr 121 + */ 122 + retval = p9_client_xattrcreate(fid, name, value_len, flags); 123 + if (retval < 0) { 124 + P9_DPRINTK(P9_DEBUG_VFS, 125 + "p9_client_xattrcreate failed %d\n", retval); 126 + goto error; 127 + } 128 + msize = fid->clnt->msize;; 129 + while (value_len) { 130 + if (value_len > (msize - P9_IOHDRSZ)) 131 + write_count = msize - P9_IOHDRSZ; 132 + else 133 + write_count = value_len; 134 + write_count = p9_client_write(fid, ((char *)value)+offset, 135 + 0, offset, write_count); 136 + if (write_count < 0) { 137 + /* error in xattr write */ 138 + retval = write_count; 139 + goto error; 140 + } 141 + offset += write_count; 142 + value_len -= write_count; 143 + } 144 + /* Total read xattr bytes */ 145 + retval = offset; 146 + error: 147 + if (fid) 148 + retval = p9_client_clunk(fid); 149 + return retval; 150 + } 151 + 152 + ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 153 + { 154 + return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); 155 + } 156 + 157 + const struct xattr_handler *v9fs_xattr_handlers[] = { 158 + &v9fs_xattr_user_handler, 159 + NULL 160 + };
+27
fs/9p/xattr.h
··· 1 + /* 2 + * Copyright IBM Corporation, 2010 3 + * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of version 2.1 of the GNU Lesser General Public License 7 + * as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it would be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 + * 13 + */ 14 + #ifndef FS_9P_XATTR_H 15 + #define FS_9P_XATTR_H 16 + 17 + #include <linux/xattr.h> 18 + 19 + extern const struct xattr_handler *v9fs_xattr_handlers[]; 20 + extern struct xattr_handler v9fs_xattr_user_handler; 21 + 22 + extern ssize_t v9fs_xattr_get(struct dentry *, const char *, 23 + void *, size_t); 24 + extern int v9fs_xattr_set(struct dentry *, const char *, 25 + const void *, size_t, int); 26 + extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t); 27 + #endif /* FS_9P_XATTR_H */
+80
fs/9p/xattr_user.c
··· 1 + /* 2 + * Copyright IBM Corporation, 2010 3 + * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of version 2.1 of the GNU Lesser General Public License 7 + * as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it would be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 + * 13 + */ 14 + 15 + 16 + #include <linux/module.h> 17 + #include <linux/string.h> 18 + #include <linux/fs.h> 19 + #include <linux/slab.h> 20 + #include "xattr.h" 21 + 22 + static int v9fs_xattr_user_get(struct dentry *dentry, const char *name, 23 + void *buffer, size_t size, int type) 24 + { 25 + int retval; 26 + char *full_name; 27 + size_t name_len; 28 + size_t prefix_len = XATTR_USER_PREFIX_LEN; 29 + 30 + if (name == NULL) 31 + return -EINVAL; 32 + 33 + if (strcmp(name, "") == 0) 34 + return -EINVAL; 35 + 36 + name_len = strlen(name); 37 + full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); 38 + if (!full_name) 39 + return -ENOMEM; 40 + memcpy(full_name, XATTR_USER_PREFIX, prefix_len); 41 + memcpy(full_name+prefix_len, name, name_len); 42 + full_name[prefix_len + name_len] = '\0'; 43 + 44 + retval = v9fs_xattr_get(dentry, full_name, buffer, size); 45 + kfree(full_name); 46 + return retval; 47 + } 48 + 49 + static int v9fs_xattr_user_set(struct dentry *dentry, const char *name, 50 + const void *value, size_t size, int flags, int type) 51 + { 52 + int retval; 53 + char *full_name; 54 + size_t name_len; 55 + size_t prefix_len = XATTR_USER_PREFIX_LEN; 56 + 57 + if (name == NULL) 58 + return -EINVAL; 59 + 60 + if (strcmp(name, "") == 0) 61 + return -EINVAL; 62 + 63 + name_len = strlen(name); 64 + full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); 65 + if (!full_name) 66 + return -ENOMEM; 67 + memcpy(full_name, XATTR_USER_PREFIX, prefix_len); 68 + memcpy(full_name + prefix_len, name, name_len); 69 + full_name[prefix_len + name_len] = '\0'; 70 + 71 + retval = v9fs_xattr_set(dentry, full_name, value, size, flags); 72 + kfree(full_name); 73 + return retval; 74 + } 75 + 76 + struct xattr_handler v9fs_xattr_user_handler = { 77 + .prefix = XATTR_USER_PREFIX, 78 + .get = v9fs_xattr_user_get, 79 + .set = v9fs_xattr_user_set, 80 + };