1 /* 2 * fs/f2fs/xattr.c 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * Portions of this code from linux/fs/ext2/xattr.c 8 * 9 * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de> 10 * 11 * Fix by Harrison Xing <harrison@mountainviewdata.com>. 12 * Extended attributes for symlinks and special files added per 13 * suggestion of Luka Renko <luka.renko@hermes.si>. 14 * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>, 15 * Red Hat Inc. 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License version 2 as 19 * published by the Free Software Foundation. 20 */ 21 #include <linux/rwsem.h> 22 #include <linux/f2fs_fs.h> 23 #include "f2fs.h" 24 #include "xattr.h" 25 26 static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, 27 size_t list_size, const char *name, size_t name_len, int type) 28 { 29 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); 30 int total_len, prefix_len = 0; 31 const char *prefix = NULL; 32 33 switch (type) { 34 case F2FS_XATTR_INDEX_USER: 35 if (!test_opt(sbi, XATTR_USER)) 36 return -EOPNOTSUPP; 37 prefix = XATTR_USER_PREFIX; 38 prefix_len = XATTR_USER_PREFIX_LEN; 39 break; 40 case F2FS_XATTR_INDEX_TRUSTED: 41 if (!capable(CAP_SYS_ADMIN)) 42 return -EPERM; 43 prefix = XATTR_TRUSTED_PREFIX; 44 prefix_len = XATTR_TRUSTED_PREFIX_LEN; 45 break; 46 default: 47 return -EINVAL; 48 } 49 50 total_len = prefix_len + name_len + 1; 51 if (list && total_len <= list_size) { 52 memcpy(list, prefix, prefix_len); 53 memcpy(list+prefix_len, name, name_len); 54 list[prefix_len + name_len] = '\0'; 55 } 56 return total_len; 57 } 58 59 static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, 60 void *buffer, size_t size, int type) 61 { 62 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); 63 64 switch (type) { 65 case F2FS_XATTR_INDEX_USER: 66 if (!test_opt(sbi, XATTR_USER)) 67 return -EOPNOTSUPP; 68 break; 69 case F2FS_XATTR_INDEX_TRUSTED: 70 if (!capable(CAP_SYS_ADMIN)) 71 return -EPERM; 72 break; 73 default: 74 return -EINVAL; 75 } 76 if (strcmp(name, "") == 0) 77 return -EINVAL; 78 return f2fs_getxattr(dentry->d_inode, type, name, 79 buffer, size); 80 } 81 82 static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, 83 const void *value, size_t size, int flags, int type) 84 { 85 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); 86 87 switch (type) { 88 case F2FS_XATTR_INDEX_USER: 89 if (!test_opt(sbi, XATTR_USER)) 90 return -EOPNOTSUPP; 91 break; 92 case F2FS_XATTR_INDEX_TRUSTED: 93 if (!capable(CAP_SYS_ADMIN)) 94 return -EPERM; 95 break; 96 default: 97 return -EINVAL; 98 } 99 if (strcmp(name, "") == 0) 100 return -EINVAL; 101 102 return f2fs_setxattr(dentry->d_inode, type, name, value, size); 103 } 104 105 static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, 106 size_t list_size, const char *name, size_t name_len, int type) 107 { 108 const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; 109 size_t size; 110 111 if (type != F2FS_XATTR_INDEX_ADVISE) 112 return 0; 113 114 size = strlen(xname) + 1; 115 if (list && size <= list_size) 116 memcpy(list, xname, size); 117 return size; 118 } 119 120 static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name, 121 void *buffer, size_t size, int type) 122 { 123 struct inode *inode = dentry->d_inode; 124 125 if (strcmp(name, "") != 0) 126 return -EINVAL; 127 128 *((char *)buffer) = F2FS_I(inode)->i_advise; 129 return sizeof(char); 130 } 131 132 static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, 133 const void *value, size_t size, int flags, int type) 134 { 135 struct inode *inode = dentry->d_inode; 136 137 if (strcmp(name, "") != 0) 138 return -EINVAL; 139 if (!inode_owner_or_capable(inode)) 140 return -EPERM; 141 if (value == NULL) 142 return -EINVAL; 143 144 F2FS_I(inode)->i_advise |= *(char *)value; 145 return 0; 146 } 147 148 const struct xattr_handler f2fs_xattr_user_handler = { 149 .prefix = XATTR_USER_PREFIX, 150 .flags = F2FS_XATTR_INDEX_USER, 151 .list = f2fs_xattr_generic_list, 152 .get = f2fs_xattr_generic_get, 153 .set = f2fs_xattr_generic_set, 154 }; 155 156 const struct xattr_handler f2fs_xattr_trusted_handler = { 157 .prefix = XATTR_TRUSTED_PREFIX, 158 .flags = F2FS_XATTR_INDEX_TRUSTED, 159 .list = f2fs_xattr_generic_list, 160 .get = f2fs_xattr_generic_get, 161 .set = f2fs_xattr_generic_set, 162 }; 163 164 const struct xattr_handler f2fs_xattr_advise_handler = { 165 .prefix = F2FS_SYSTEM_ADVISE_PREFIX, 166 .flags = F2FS_XATTR_INDEX_ADVISE, 167 .list = f2fs_xattr_advise_list, 168 .get = f2fs_xattr_advise_get, 169 .set = f2fs_xattr_advise_set, 170 }; 171 172 static const struct xattr_handler *f2fs_xattr_handler_map[] = { 173 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler, 174 #ifdef CONFIG_F2FS_FS_POSIX_ACL 175 [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler, 176 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler, 177 #endif 178 [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler, 179 [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler, 180 }; 181 182 const struct xattr_handler *f2fs_xattr_handlers[] = { 183 &f2fs_xattr_user_handler, 184 #ifdef CONFIG_F2FS_FS_POSIX_ACL 185 &f2fs_xattr_acl_access_handler, 186 &f2fs_xattr_acl_default_handler, 187 #endif 188 &f2fs_xattr_trusted_handler, 189 &f2fs_xattr_advise_handler, 190 NULL, 191 }; 192 193 static inline const struct xattr_handler *f2fs_xattr_handler(int name_index) 194 { 195 const struct xattr_handler *handler = NULL; 196 197 if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map)) 198 handler = f2fs_xattr_handler_map[name_index]; 199 return handler; 200 } 201 202 int f2fs_getxattr(struct inode *inode, int name_index, const char *name, 203 void *buffer, size_t buffer_size) 204 { 205 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 206 struct f2fs_inode_info *fi = F2FS_I(inode); 207 struct f2fs_xattr_entry *entry; 208 struct page *page; 209 void *base_addr; 210 int error = 0, found = 0; 211 int value_len, name_len; 212 213 if (name == NULL) 214 return -EINVAL; 215 name_len = strlen(name); 216 217 if (!fi->i_xattr_nid) 218 return -ENODATA; 219 220 page = get_node_page(sbi, fi->i_xattr_nid); 221 base_addr = page_address(page); 222 223 list_for_each_xattr(entry, base_addr) { 224 if (entry->e_name_index != name_index) 225 continue; 226 if (entry->e_name_len != name_len) 227 continue; 228 if (!memcmp(entry->e_name, name, name_len)) { 229 found = 1; 230 break; 231 } 232 } 233 if (!found) { 234 error = -ENODATA; 235 goto cleanup; 236 } 237 238 value_len = le16_to_cpu(entry->e_value_size); 239 240 if (buffer && value_len > buffer_size) { 241 error = -ERANGE; 242 goto cleanup; 243 } 244 245 if (buffer) { 246 char *pval = entry->e_name + entry->e_name_len; 247 memcpy(buffer, pval, value_len); 248 } 249 error = value_len; 250 251 cleanup: 252 f2fs_put_page(page, 1); 253 return error; 254 } 255 256 ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 257 { 258 struct inode *inode = dentry->d_inode; 259 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 260 struct f2fs_inode_info *fi = F2FS_I(inode); 261 struct f2fs_xattr_entry *entry; 262 struct page *page; 263 void *base_addr; 264 int error = 0; 265 size_t rest = buffer_size; 266 267 if (!fi->i_xattr_nid) 268 return 0; 269 270 page = get_node_page(sbi, fi->i_xattr_nid); 271 base_addr = page_address(page); 272 273 list_for_each_xattr(entry, base_addr) { 274 const struct xattr_handler *handler = 275 f2fs_xattr_handler(entry->e_name_index); 276 size_t size; 277 278 if (!handler) 279 continue; 280 281 size = handler->list(dentry, buffer, rest, entry->e_name, 282 entry->e_name_len, handler->flags); 283 if (buffer && size > rest) { 284 error = -ERANGE; 285 goto cleanup; 286 } 287 288 if (buffer) 289 buffer += size; 290 rest -= size; 291 } 292 error = buffer_size - rest; 293 cleanup: 294 f2fs_put_page(page, 1); 295 return error; 296 } 297 298 int f2fs_setxattr(struct inode *inode, int name_index, const char *name, 299 const void *value, size_t value_len) 300 { 301 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 302 struct f2fs_inode_info *fi = F2FS_I(inode); 303 struct f2fs_xattr_header *header = NULL; 304 struct f2fs_xattr_entry *here, *last; 305 struct page *page; 306 void *base_addr; 307 int error, found, free, name_len, newsize; 308 char *pval; 309 310 if (name == NULL) 311 return -EINVAL; 312 name_len = strlen(name); 313 314 if (value == NULL) 315 value_len = 0; 316 317 if (name_len > 255 || value_len > MAX_VALUE_LEN) 318 return -ERANGE; 319 320 mutex_lock_op(sbi, NODE_NEW); 321 if (!fi->i_xattr_nid) { 322 /* Allocate new attribute block */ 323 struct dnode_of_data dn; 324 325 if (!alloc_nid(sbi, &fi->i_xattr_nid)) { 326 mutex_unlock_op(sbi, NODE_NEW); 327 return -ENOSPC; 328 } 329 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid); 330 mark_inode_dirty(inode); 331 332 page = new_node_page(&dn, XATTR_NODE_OFFSET); 333 if (IS_ERR(page)) { 334 alloc_nid_failed(sbi, fi->i_xattr_nid); 335 fi->i_xattr_nid = 0; 336 mutex_unlock_op(sbi, NODE_NEW); 337 return PTR_ERR(page); 338 } 339 340 alloc_nid_done(sbi, fi->i_xattr_nid); 341 base_addr = page_address(page); 342 header = XATTR_HDR(base_addr); 343 header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC); 344 header->h_refcount = cpu_to_le32(1); 345 } else { 346 /* The inode already has an extended attribute block. */ 347 page = get_node_page(sbi, fi->i_xattr_nid); 348 if (IS_ERR(page)) { 349 mutex_unlock_op(sbi, NODE_NEW); 350 return PTR_ERR(page); 351 } 352 353 base_addr = page_address(page); 354 header = XATTR_HDR(base_addr); 355 } 356 357 if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) { 358 error = -EIO; 359 goto cleanup; 360 } 361 362 /* find entry with wanted name. */ 363 found = 0; 364 list_for_each_xattr(here, base_addr) { 365 if (here->e_name_index != name_index) 366 continue; 367 if (here->e_name_len != name_len) 368 continue; 369 if (!memcmp(here->e_name, name, name_len)) { 370 found = 1; 371 break; 372 } 373 } 374 375 last = here; 376 377 while (!IS_XATTR_LAST_ENTRY(last)) 378 last = XATTR_NEXT_ENTRY(last); 379 380 newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + 381 name_len + value_len); 382 383 /* 1. Check space */ 384 if (value) { 385 /* If value is NULL, it is remove operation. 386 * In case of update operation, we caculate free. 387 */ 388 free = MIN_OFFSET - ((char *)last - (char *)header); 389 if (found) 390 free = free - ENTRY_SIZE(here); 391 392 if (free < newsize) { 393 error = -ENOSPC; 394 goto cleanup; 395 } 396 } 397 398 /* 2. Remove old entry */ 399 if (found) { 400 /* If entry is found, remove old entry. 401 * If not found, remove operation is not needed. 402 */ 403 struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here); 404 int oldsize = ENTRY_SIZE(here); 405 406 memmove(here, next, (char *)last - (char *)next); 407 last = (struct f2fs_xattr_entry *)((char *)last - oldsize); 408 memset(last, 0, oldsize); 409 } 410 411 /* 3. Write new entry */ 412 if (value) { 413 /* Before we come here, old entry is removed. 414 * We just write new entry. */ 415 memset(last, 0, newsize); 416 last->e_name_index = name_index; 417 last->e_name_len = name_len; 418 memcpy(last->e_name, name, name_len); 419 pval = last->e_name + name_len; 420 memcpy(pval, value, value_len); 421 last->e_value_size = cpu_to_le16(value_len); 422 } 423 424 set_page_dirty(page); 425 f2fs_put_page(page, 1); 426 427 if (is_inode_flag_set(fi, FI_ACL_MODE)) { 428 inode->i_mode = fi->i_acl_mode; 429 inode->i_ctime = CURRENT_TIME; 430 clear_inode_flag(fi, FI_ACL_MODE); 431 } 432 f2fs_write_inode(inode, NULL); 433 mutex_unlock_op(sbi, NODE_NEW); 434 435 return 0; 436 cleanup: 437 f2fs_put_page(page, 1); 438 mutex_unlock_op(sbi, NODE_NEW); 439 return error; 440 } 441