xattr.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. * (C) 2001 Clemson University and The University of Chicago
  3. *
  4. * See COPYING in top-level directory.
  5. */
  6. /*
  7. * Linux VFS extended attribute operations.
  8. */
  9. #include "protocol.h"
  10. #include "orangefs-kernel.h"
  11. #include "orangefs-bufmap.h"
  12. #include <linux/posix_acl_xattr.h>
  13. #include <linux/xattr.h>
  14. #define SYSTEM_ORANGEFS_KEY "system.pvfs2."
  15. #define SYSTEM_ORANGEFS_KEY_LEN 13
  16. /*
  17. * this function returns
  18. * 0 if the key corresponding to name is not meant to be printed as part
  19. * of a listxattr.
  20. * 1 if the key corresponding to name is meant to be returned as part of
  21. * a listxattr.
  22. * The ones that start SYSTEM_ORANGEFS_KEY are the ones to avoid printing.
  23. */
  24. static int is_reserved_key(const char *key, size_t size)
  25. {
  26. if (size < SYSTEM_ORANGEFS_KEY_LEN)
  27. return 1;
  28. return strncmp(key, SYSTEM_ORANGEFS_KEY, SYSTEM_ORANGEFS_KEY_LEN) ? 1 : 0;
  29. }
  30. static inline int convert_to_internal_xattr_flags(int setxattr_flags)
  31. {
  32. int internal_flag = 0;
  33. if (setxattr_flags & XATTR_REPLACE) {
  34. /* Attribute must exist! */
  35. internal_flag = ORANGEFS_XATTR_REPLACE;
  36. } else if (setxattr_flags & XATTR_CREATE) {
  37. /* Attribute must not exist */
  38. internal_flag = ORANGEFS_XATTR_CREATE;
  39. }
  40. return internal_flag;
  41. }
  42. /*
  43. * Tries to get a specified key's attributes of a given
  44. * file into a user-specified buffer. Note that the getxattr
  45. * interface allows for the users to probe the size of an
  46. * extended attribute by passing in a value of 0 to size.
  47. * Thus our return value is always the size of the attribute
  48. * unless the key does not exist for the file and/or if
  49. * there were errors in fetching the attribute value.
  50. */
  51. ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
  52. const char *name, void *buffer, size_t size)
  53. {
  54. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  55. struct orangefs_kernel_op_s *new_op = NULL;
  56. ssize_t ret = -ENOMEM;
  57. ssize_t length = 0;
  58. int fsuid;
  59. int fsgid;
  60. gossip_debug(GOSSIP_XATTR_DEBUG,
  61. "%s: prefix %s name %s, buffer_size %zd\n",
  62. __func__, prefix, name, size);
  63. if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) {
  64. gossip_err("Invalid key length (%d)\n",
  65. (int)(strlen(name) + strlen(prefix)));
  66. return -EINVAL;
  67. }
  68. fsuid = from_kuid(current_user_ns(), current_fsuid());
  69. fsgid = from_kgid(current_user_ns(), current_fsgid());
  70. gossip_debug(GOSSIP_XATTR_DEBUG,
  71. "getxattr on inode %pU, name %s "
  72. "(uid %o, gid %o)\n",
  73. get_khandle_from_ino(inode),
  74. name,
  75. fsuid,
  76. fsgid);
  77. down_read(&orangefs_inode->xattr_sem);
  78. new_op = op_alloc(ORANGEFS_VFS_OP_GETXATTR);
  79. if (!new_op)
  80. goto out_unlock;
  81. new_op->upcall.req.getxattr.refn = orangefs_inode->refn;
  82. ret = snprintf((char *)new_op->upcall.req.getxattr.key,
  83. ORANGEFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name);
  84. /*
  85. * NOTE: Although keys are meant to be NULL terminated textual
  86. * strings, I am going to explicitly pass the length just in case
  87. * we change this later on...
  88. */
  89. new_op->upcall.req.getxattr.key_sz = ret + 1;
  90. ret = service_operation(new_op, "orangefs_inode_getxattr",
  91. get_interruptible_flag(inode));
  92. if (ret != 0) {
  93. if (ret == -ENOENT) {
  94. ret = -ENODATA;
  95. gossip_debug(GOSSIP_XATTR_DEBUG,
  96. "orangefs_inode_getxattr: inode %pU key %s"
  97. " does not exist!\n",
  98. get_khandle_from_ino(inode),
  99. (char *)new_op->upcall.req.getxattr.key);
  100. }
  101. goto out_release_op;
  102. }
  103. /*
  104. * Length returned includes null terminator.
  105. */
  106. length = new_op->downcall.resp.getxattr.val_sz;
  107. /*
  108. * Just return the length of the queried attribute.
  109. */
  110. if (size == 0) {
  111. ret = length;
  112. goto out_release_op;
  113. }
  114. /*
  115. * Check to see if key length is > provided buffer size.
  116. */
  117. if (length > size) {
  118. ret = -ERANGE;
  119. goto out_release_op;
  120. }
  121. memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
  122. memset(buffer + length, 0, size - length);
  123. gossip_debug(GOSSIP_XATTR_DEBUG,
  124. "orangefs_inode_getxattr: inode %pU "
  125. "key %s key_sz %d, val_len %d\n",
  126. get_khandle_from_ino(inode),
  127. (char *)new_op->
  128. upcall.req.getxattr.key,
  129. (int)new_op->
  130. upcall.req.getxattr.key_sz,
  131. (int)ret);
  132. ret = length;
  133. out_release_op:
  134. op_release(new_op);
  135. out_unlock:
  136. up_read(&orangefs_inode->xattr_sem);
  137. return ret;
  138. }
  139. static int orangefs_inode_removexattr(struct inode *inode,
  140. const char *prefix,
  141. const char *name,
  142. int flags)
  143. {
  144. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  145. struct orangefs_kernel_op_s *new_op = NULL;
  146. int ret = -ENOMEM;
  147. down_write(&orangefs_inode->xattr_sem);
  148. new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR);
  149. if (!new_op)
  150. goto out_unlock;
  151. new_op->upcall.req.removexattr.refn = orangefs_inode->refn;
  152. /*
  153. * NOTE: Although keys are meant to be NULL terminated
  154. * textual strings, I am going to explicitly pass the
  155. * length just in case we change this later on...
  156. */
  157. ret = snprintf((char *)new_op->upcall.req.removexattr.key,
  158. ORANGEFS_MAX_XATTR_NAMELEN,
  159. "%s%s",
  160. (prefix ? prefix : ""),
  161. name);
  162. new_op->upcall.req.removexattr.key_sz = ret + 1;
  163. gossip_debug(GOSSIP_XATTR_DEBUG,
  164. "orangefs_inode_removexattr: key %s, key_sz %d\n",
  165. (char *)new_op->upcall.req.removexattr.key,
  166. (int)new_op->upcall.req.removexattr.key_sz);
  167. ret = service_operation(new_op,
  168. "orangefs_inode_removexattr",
  169. get_interruptible_flag(inode));
  170. if (ret == -ENOENT) {
  171. /*
  172. * Request to replace a non-existent attribute is an error.
  173. */
  174. if (flags & XATTR_REPLACE)
  175. ret = -ENODATA;
  176. else
  177. ret = 0;
  178. }
  179. gossip_debug(GOSSIP_XATTR_DEBUG,
  180. "orangefs_inode_removexattr: returning %d\n", ret);
  181. op_release(new_op);
  182. out_unlock:
  183. up_write(&orangefs_inode->xattr_sem);
  184. return ret;
  185. }
  186. /*
  187. * Tries to set an attribute for a given key on a file.
  188. *
  189. * Returns a -ve number on error and 0 on success. Key is text, but value
  190. * can be binary!
  191. */
  192. int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
  193. const char *name, const void *value, size_t size, int flags)
  194. {
  195. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  196. struct orangefs_kernel_op_s *new_op;
  197. int internal_flag = 0;
  198. int ret = -ENOMEM;
  199. gossip_debug(GOSSIP_XATTR_DEBUG,
  200. "%s: prefix %s, name %s, buffer_size %zd\n",
  201. __func__, prefix, name, size);
  202. if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
  203. flags < 0) {
  204. gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
  205. (int)size,
  206. flags);
  207. return -EINVAL;
  208. }
  209. internal_flag = convert_to_internal_xattr_flags(flags);
  210. if (prefix) {
  211. if (strlen(name) + strlen(prefix) >= ORANGEFS_MAX_XATTR_NAMELEN) {
  212. gossip_err
  213. ("orangefs_inode_setxattr: bogus key size (%d)\n",
  214. (int)(strlen(name) + strlen(prefix)));
  215. return -EINVAL;
  216. }
  217. } else {
  218. if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) {
  219. gossip_err
  220. ("orangefs_inode_setxattr: bogus key size (%d)\n",
  221. (int)(strlen(name)));
  222. return -EINVAL;
  223. }
  224. }
  225. /* This is equivalent to a removexattr */
  226. if (size == 0 && value == NULL) {
  227. gossip_debug(GOSSIP_XATTR_DEBUG,
  228. "removing xattr (%s%s)\n",
  229. prefix,
  230. name);
  231. return orangefs_inode_removexattr(inode, prefix, name, flags);
  232. }
  233. gossip_debug(GOSSIP_XATTR_DEBUG,
  234. "setxattr on inode %pU, name %s\n",
  235. get_khandle_from_ino(inode),
  236. name);
  237. down_write(&orangefs_inode->xattr_sem);
  238. new_op = op_alloc(ORANGEFS_VFS_OP_SETXATTR);
  239. if (!new_op)
  240. goto out_unlock;
  241. new_op->upcall.req.setxattr.refn = orangefs_inode->refn;
  242. new_op->upcall.req.setxattr.flags = internal_flag;
  243. /*
  244. * NOTE: Although keys are meant to be NULL terminated textual
  245. * strings, I am going to explicitly pass the length just in
  246. * case we change this later on...
  247. */
  248. ret = snprintf((char *)new_op->upcall.req.setxattr.keyval.key,
  249. ORANGEFS_MAX_XATTR_NAMELEN,
  250. "%s%s",
  251. prefix, name);
  252. new_op->upcall.req.setxattr.keyval.key_sz = ret + 1;
  253. memcpy(new_op->upcall.req.setxattr.keyval.val, value, size);
  254. new_op->upcall.req.setxattr.keyval.val_sz = size;
  255. gossip_debug(GOSSIP_XATTR_DEBUG,
  256. "orangefs_inode_setxattr: key %s, key_sz %d "
  257. " value size %zd\n",
  258. (char *)new_op->upcall.req.setxattr.keyval.key,
  259. (int)new_op->upcall.req.setxattr.keyval.key_sz,
  260. size);
  261. ret = service_operation(new_op,
  262. "orangefs_inode_setxattr",
  263. get_interruptible_flag(inode));
  264. gossip_debug(GOSSIP_XATTR_DEBUG,
  265. "orangefs_inode_setxattr: returning %d\n",
  266. ret);
  267. /* when request is serviced properly, free req op struct */
  268. op_release(new_op);
  269. out_unlock:
  270. up_write(&orangefs_inode->xattr_sem);
  271. return ret;
  272. }
  273. /*
  274. * Tries to get a specified object's keys into a user-specified buffer of a
  275. * given size. Note that like the previous instances of xattr routines, this
  276. * also allows you to pass in a NULL pointer and 0 size to probe the size for
  277. * subsequent memory allocations. Thus our return value is always the size of
  278. * all the keys unless there were errors in fetching the keys!
  279. */
  280. ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
  281. {
  282. struct inode *inode = dentry->d_inode;
  283. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  284. struct orangefs_kernel_op_s *new_op;
  285. __u64 token = ORANGEFS_ITERATE_START;
  286. ssize_t ret = -ENOMEM;
  287. ssize_t total = 0;
  288. int count_keys = 0;
  289. int key_size;
  290. int i = 0;
  291. int returned_count = 0;
  292. if (size > 0 && buffer == NULL) {
  293. gossip_err("%s: bogus NULL pointers\n", __func__);
  294. return -EINVAL;
  295. }
  296. down_read(&orangefs_inode->xattr_sem);
  297. new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);
  298. if (!new_op)
  299. goto out_unlock;
  300. if (buffer && size > 0)
  301. memset(buffer, 0, size);
  302. try_again:
  303. key_size = 0;
  304. new_op->upcall.req.listxattr.refn = orangefs_inode->refn;
  305. new_op->upcall.req.listxattr.token = token;
  306. new_op->upcall.req.listxattr.requested_count =
  307. (size == 0) ? 0 : ORANGEFS_MAX_XATTR_LISTLEN;
  308. ret = service_operation(new_op, __func__,
  309. get_interruptible_flag(inode));
  310. if (ret != 0)
  311. goto done;
  312. if (size == 0) {
  313. /*
  314. * This is a bit of a big upper limit, but I did not want to
  315. * spend too much time getting this correct, since users end
  316. * up allocating memory rather than us...
  317. */
  318. total = new_op->downcall.resp.listxattr.returned_count *
  319. ORANGEFS_MAX_XATTR_NAMELEN;
  320. goto done;
  321. }
  322. returned_count = new_op->downcall.resp.listxattr.returned_count;
  323. if (returned_count < 0 ||
  324. returned_count >= ORANGEFS_MAX_XATTR_LISTLEN) {
  325. gossip_err("%s: impossible value for returned_count:%d:\n",
  326. __func__,
  327. returned_count);
  328. ret = -EIO;
  329. goto done;
  330. }
  331. /*
  332. * Check to see how much can be fit in the buffer. Fit only whole keys.
  333. */
  334. for (i = 0; i < returned_count; i++) {
  335. if (new_op->downcall.resp.listxattr.lengths[i] < 0 ||
  336. new_op->downcall.resp.listxattr.lengths[i] >
  337. ORANGEFS_MAX_XATTR_NAMELEN) {
  338. gossip_err("%s: impossible value for lengths[%d]\n",
  339. __func__,
  340. new_op->downcall.resp.listxattr.lengths[i]);
  341. ret = -EIO;
  342. goto done;
  343. }
  344. if (total + new_op->downcall.resp.listxattr.lengths[i] > size)
  345. goto done;
  346. /*
  347. * Since many dumb programs try to setxattr() on our reserved
  348. * xattrs this is a feeble attempt at defeating those by not
  349. * listing them in the output of listxattr.. sigh
  350. */
  351. if (is_reserved_key(new_op->downcall.resp.listxattr.key +
  352. key_size,
  353. new_op->downcall.resp.
  354. listxattr.lengths[i])) {
  355. gossip_debug(GOSSIP_XATTR_DEBUG, "Copying key %d -> %s\n",
  356. i, new_op->downcall.resp.listxattr.key +
  357. key_size);
  358. memcpy(buffer + total,
  359. new_op->downcall.resp.listxattr.key + key_size,
  360. new_op->downcall.resp.listxattr.lengths[i]);
  361. total += new_op->downcall.resp.listxattr.lengths[i];
  362. count_keys++;
  363. } else {
  364. gossip_debug(GOSSIP_XATTR_DEBUG, "[RESERVED] key %d -> %s\n",
  365. i, new_op->downcall.resp.listxattr.key +
  366. key_size);
  367. }
  368. key_size += new_op->downcall.resp.listxattr.lengths[i];
  369. }
  370. /*
  371. * Since the buffer was large enough, we might have to continue
  372. * fetching more keys!
  373. */
  374. token = new_op->downcall.resp.listxattr.token;
  375. if (token != ORANGEFS_ITERATE_END)
  376. goto try_again;
  377. done:
  378. gossip_debug(GOSSIP_XATTR_DEBUG, "%s: returning %d"
  379. " [size of buffer %ld] (filled in %d keys)\n",
  380. __func__,
  381. ret ? (int)ret : (int)total,
  382. (long)size,
  383. count_keys);
  384. op_release(new_op);
  385. if (ret == 0)
  386. ret = total;
  387. out_unlock:
  388. up_read(&orangefs_inode->xattr_sem);
  389. return ret;
  390. }
  391. static int orangefs_xattr_set_default(const struct xattr_handler *handler,
  392. struct dentry *dentry,
  393. const char *name,
  394. const void *buffer,
  395. size_t size,
  396. int flags)
  397. {
  398. return orangefs_inode_setxattr(dentry->d_inode,
  399. ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
  400. name,
  401. buffer,
  402. size,
  403. flags);
  404. }
  405. static int orangefs_xattr_get_default(const struct xattr_handler *handler,
  406. struct dentry *dentry,
  407. const char *name,
  408. void *buffer,
  409. size_t size)
  410. {
  411. return orangefs_inode_getxattr(dentry->d_inode,
  412. ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
  413. name,
  414. buffer,
  415. size);
  416. }
  417. static int orangefs_xattr_set_trusted(const struct xattr_handler *handler,
  418. struct dentry *dentry,
  419. const char *name,
  420. const void *buffer,
  421. size_t size,
  422. int flags)
  423. {
  424. return orangefs_inode_setxattr(dentry->d_inode,
  425. ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
  426. name,
  427. buffer,
  428. size,
  429. flags);
  430. }
  431. static int orangefs_xattr_get_trusted(const struct xattr_handler *handler,
  432. struct dentry *dentry,
  433. const char *name,
  434. void *buffer,
  435. size_t size)
  436. {
  437. return orangefs_inode_getxattr(dentry->d_inode,
  438. ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
  439. name,
  440. buffer,
  441. size);
  442. }
  443. static struct xattr_handler orangefs_xattr_trusted_handler = {
  444. .prefix = ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
  445. .get = orangefs_xattr_get_trusted,
  446. .set = orangefs_xattr_set_trusted,
  447. };
  448. static struct xattr_handler orangefs_xattr_default_handler = {
  449. /*
  450. * NOTE: this is set to be the empty string.
  451. * so that all un-prefixed xattrs keys get caught
  452. * here!
  453. */
  454. .prefix = ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
  455. .get = orangefs_xattr_get_default,
  456. .set = orangefs_xattr_set_default,
  457. };
  458. const struct xattr_handler *orangefs_xattr_handlers[] = {
  459. &posix_acl_access_xattr_handler,
  460. &posix_acl_default_xattr_handler,
  461. &orangefs_xattr_trusted_handler,
  462. &orangefs_xattr_default_handler,
  463. NULL
  464. };