xattr.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. #include "ceph_debug.h"
  2. #include "super.h"
  3. #include "decode.h"
  4. #include <linux/xattr.h>
  5. static bool ceph_is_valid_xattr(const char *name)
  6. {
  7. return !strncmp(name, XATTR_SECURITY_PREFIX,
  8. XATTR_SECURITY_PREFIX_LEN) ||
  9. !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
  10. !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
  11. }
  12. /*
  13. * These define virtual xattrs exposing the recursive directory
  14. * statistics and layout metadata.
  15. */
  16. struct ceph_vxattr_cb {
  17. bool readonly;
  18. char *name;
  19. size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
  20. size_t size);
  21. };
  22. /* directories */
  23. static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val,
  24. size_t size)
  25. {
  26. return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs);
  27. }
  28. static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val,
  29. size_t size)
  30. {
  31. return snprintf(val, size, "%lld", ci->i_files);
  32. }
  33. static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val,
  34. size_t size)
  35. {
  36. return snprintf(val, size, "%lld", ci->i_subdirs);
  37. }
  38. static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val,
  39. size_t size)
  40. {
  41. return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs);
  42. }
  43. static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val,
  44. size_t size)
  45. {
  46. return snprintf(val, size, "%lld", ci->i_rfiles);
  47. }
  48. static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val,
  49. size_t size)
  50. {
  51. return snprintf(val, size, "%lld", ci->i_rsubdirs);
  52. }
  53. static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val,
  54. size_t size)
  55. {
  56. return snprintf(val, size, "%lld", ci->i_rbytes);
  57. }
  58. static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val,
  59. size_t size)
  60. {
  61. return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec,
  62. (long)ci->i_rctime.tv_nsec);
  63. }
  64. static struct ceph_vxattr_cb ceph_dir_vxattrs[] = {
  65. { true, "user.ceph.dir.entries", ceph_vxattrcb_entries},
  66. { true, "user.ceph.dir.files", ceph_vxattrcb_files},
  67. { true, "user.ceph.dir.subdirs", ceph_vxattrcb_subdirs},
  68. { true, "user.ceph.dir.rentries", ceph_vxattrcb_rentries},
  69. { true, "user.ceph.dir.rfiles", ceph_vxattrcb_rfiles},
  70. { true, "user.ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs},
  71. { true, "user.ceph.dir.rbytes", ceph_vxattrcb_rbytes},
  72. { true, "user.ceph.dir.rctime", ceph_vxattrcb_rctime},
  73. { true, NULL, NULL }
  74. };
  75. /* files */
  76. static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
  77. size_t size)
  78. {
  79. int ret;
  80. ret = snprintf(val, size,
  81. "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n",
  82. (unsigned long long)ceph_file_layout_su(ci->i_layout),
  83. (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
  84. (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
  85. if (ceph_file_layout_pg_preferred(ci->i_layout))
  86. ret += snprintf(val + ret, size, "preferred_osd=%lld\n",
  87. (unsigned long long)ceph_file_layout_pg_preferred(
  88. ci->i_layout));
  89. return ret;
  90. }
  91. static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
  92. { true, "user.ceph.layout", ceph_vxattrcb_layout},
  93. { NULL, NULL }
  94. };
  95. static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
  96. {
  97. if (S_ISDIR(inode->i_mode))
  98. return ceph_dir_vxattrs;
  99. else if (S_ISREG(inode->i_mode))
  100. return ceph_file_vxattrs;
  101. return NULL;
  102. }
  103. static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr,
  104. const char *name)
  105. {
  106. do {
  107. if (strcmp(vxattr->name, name) == 0)
  108. return vxattr;
  109. vxattr++;
  110. } while (vxattr->name);
  111. return NULL;
  112. }
  113. static int __set_xattr(struct ceph_inode_info *ci,
  114. const char *name, int name_len,
  115. const char *val, int val_len,
  116. int dirty,
  117. int should_free_name, int should_free_val,
  118. struct ceph_inode_xattr **newxattr)
  119. {
  120. struct rb_node **p;
  121. struct rb_node *parent = NULL;
  122. struct ceph_inode_xattr *xattr = NULL;
  123. int c;
  124. int new = 0;
  125. p = &ci->i_xattrs.index.rb_node;
  126. while (*p) {
  127. parent = *p;
  128. xattr = rb_entry(parent, struct ceph_inode_xattr, node);
  129. c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
  130. if (c < 0)
  131. p = &(*p)->rb_left;
  132. else if (c > 0)
  133. p = &(*p)->rb_right;
  134. else {
  135. if (name_len == xattr->name_len)
  136. break;
  137. else if (name_len < xattr->name_len)
  138. p = &(*p)->rb_left;
  139. else
  140. p = &(*p)->rb_right;
  141. }
  142. xattr = NULL;
  143. }
  144. if (!xattr) {
  145. new = 1;
  146. xattr = *newxattr;
  147. xattr->name = name;
  148. xattr->name_len = name_len;
  149. xattr->should_free_name = should_free_name;
  150. ci->i_xattrs.count++;
  151. dout("__set_xattr count=%d\n", ci->i_xattrs.count);
  152. } else {
  153. kfree(*newxattr);
  154. *newxattr = NULL;
  155. if (xattr->should_free_val)
  156. kfree((void *)xattr->val);
  157. if (should_free_name) {
  158. kfree((void *)name);
  159. name = xattr->name;
  160. }
  161. ci->i_xattrs.names_size -= xattr->name_len;
  162. ci->i_xattrs.vals_size -= xattr->val_len;
  163. }
  164. if (!xattr) {
  165. pr_err("__set_xattr ENOMEM on %p %llx.%llx xattr %s=%s\n",
  166. &ci->vfs_inode, ceph_vinop(&ci->vfs_inode), name,
  167. xattr->val);
  168. return -ENOMEM;
  169. }
  170. ci->i_xattrs.names_size += name_len;
  171. ci->i_xattrs.vals_size += val_len;
  172. if (val)
  173. xattr->val = val;
  174. else
  175. xattr->val = "";
  176. xattr->val_len = val_len;
  177. xattr->dirty = dirty;
  178. xattr->should_free_val = (val && should_free_val);
  179. if (new) {
  180. rb_link_node(&xattr->node, parent, p);
  181. rb_insert_color(&xattr->node, &ci->i_xattrs.index);
  182. dout("__set_xattr_val p=%p\n", p);
  183. }
  184. dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n",
  185. ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val);
  186. return 0;
  187. }
  188. static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
  189. const char *name)
  190. {
  191. struct rb_node **p;
  192. struct rb_node *parent = NULL;
  193. struct ceph_inode_xattr *xattr = NULL;
  194. int c;
  195. p = &ci->i_xattrs.index.rb_node;
  196. while (*p) {
  197. parent = *p;
  198. xattr = rb_entry(parent, struct ceph_inode_xattr, node);
  199. c = strncmp(name, xattr->name, xattr->name_len);
  200. if (c < 0)
  201. p = &(*p)->rb_left;
  202. else if (c > 0)
  203. p = &(*p)->rb_right;
  204. else {
  205. dout("__get_xattr %s: found %.*s\n", name,
  206. xattr->val_len, xattr->val);
  207. return xattr;
  208. }
  209. }
  210. dout("__get_xattr %s: not found\n", name);
  211. return NULL;
  212. }
  213. static void __free_xattr(struct ceph_inode_xattr *xattr)
  214. {
  215. BUG_ON(!xattr);
  216. if (xattr->should_free_name)
  217. kfree((void *)xattr->name);
  218. if (xattr->should_free_val)
  219. kfree((void *)xattr->val);
  220. kfree(xattr);
  221. }
  222. static int __remove_xattr(struct ceph_inode_info *ci,
  223. struct ceph_inode_xattr *xattr)
  224. {
  225. if (!xattr)
  226. return -EOPNOTSUPP;
  227. rb_erase(&xattr->node, &ci->i_xattrs.index);
  228. if (xattr->should_free_name)
  229. kfree((void *)xattr->name);
  230. if (xattr->should_free_val)
  231. kfree((void *)xattr->val);
  232. ci->i_xattrs.names_size -= xattr->name_len;
  233. ci->i_xattrs.vals_size -= xattr->val_len;
  234. ci->i_xattrs.count--;
  235. kfree(xattr);
  236. return 0;
  237. }
  238. static int __remove_xattr_by_name(struct ceph_inode_info *ci,
  239. const char *name)
  240. {
  241. struct rb_node **p;
  242. struct ceph_inode_xattr *xattr;
  243. int err;
  244. p = &ci->i_xattrs.index.rb_node;
  245. xattr = __get_xattr(ci, name);
  246. err = __remove_xattr(ci, xattr);
  247. return err;
  248. }
  249. static char *__copy_xattr_names(struct ceph_inode_info *ci,
  250. char *dest)
  251. {
  252. struct rb_node *p;
  253. struct ceph_inode_xattr *xattr = NULL;
  254. p = rb_first(&ci->i_xattrs.index);
  255. dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
  256. while (p) {
  257. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  258. memcpy(dest, xattr->name, xattr->name_len);
  259. dest[xattr->name_len] = '\0';
  260. dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
  261. xattr->name_len, ci->i_xattrs.names_size);
  262. dest += xattr->name_len + 1;
  263. p = rb_next(p);
  264. }
  265. return dest;
  266. }
  267. void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
  268. {
  269. struct rb_node *p, *tmp;
  270. struct ceph_inode_xattr *xattr = NULL;
  271. p = rb_first(&ci->i_xattrs.index);
  272. dout("__ceph_destroy_xattrs p=%p\n", p);
  273. while (p) {
  274. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  275. tmp = p;
  276. p = rb_next(tmp);
  277. dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
  278. xattr->name_len, xattr->name);
  279. rb_erase(tmp, &ci->i_xattrs.index);
  280. __free_xattr(xattr);
  281. }
  282. ci->i_xattrs.names_size = 0;
  283. ci->i_xattrs.vals_size = 0;
  284. ci->i_xattrs.index_version = 0;
  285. ci->i_xattrs.count = 0;
  286. ci->i_xattrs.index = RB_ROOT;
  287. }
  288. static int __build_xattrs(struct inode *inode)
  289. {
  290. u32 namelen;
  291. u32 numattr = 0;
  292. void *p, *end;
  293. u32 len;
  294. const char *name, *val;
  295. struct ceph_inode_info *ci = ceph_inode(inode);
  296. int xattr_version;
  297. struct ceph_inode_xattr **xattrs = NULL;
  298. int err;
  299. int i;
  300. dout("__build_xattrs() len=%d\n",
  301. ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
  302. if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
  303. return 0; /* already built */
  304. __ceph_destroy_xattrs(ci);
  305. start:
  306. /* updated internal xattr rb tree */
  307. if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
  308. p = ci->i_xattrs.blob->vec.iov_base;
  309. end = p + ci->i_xattrs.blob->vec.iov_len;
  310. ceph_decode_32_safe(&p, end, numattr, bad);
  311. xattr_version = ci->i_xattrs.version;
  312. spin_unlock(&inode->i_lock);
  313. xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *),
  314. GFP_NOFS);
  315. err = -ENOMEM;
  316. if (!xattrs)
  317. goto bad_lock;
  318. memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *));
  319. for (i = 0; i < numattr; i++) {
  320. xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
  321. GFP_NOFS);
  322. if (!xattrs[i])
  323. goto bad_lock;
  324. }
  325. spin_lock(&inode->i_lock);
  326. if (ci->i_xattrs.version != xattr_version) {
  327. /* lost a race, retry */
  328. for (i = 0; i < numattr; i++)
  329. kfree(xattrs[i]);
  330. kfree(xattrs);
  331. goto start;
  332. }
  333. err = -EIO;
  334. while (numattr--) {
  335. ceph_decode_32_safe(&p, end, len, bad);
  336. namelen = len;
  337. name = p;
  338. p += len;
  339. ceph_decode_32_safe(&p, end, len, bad);
  340. val = p;
  341. p += len;
  342. err = __set_xattr(ci, name, namelen, val, len,
  343. 0, 0, 0, &xattrs[numattr]);
  344. if (err < 0)
  345. goto bad;
  346. }
  347. kfree(xattrs);
  348. }
  349. ci->i_xattrs.index_version = ci->i_xattrs.version;
  350. ci->i_xattrs.dirty = false;
  351. return err;
  352. bad_lock:
  353. spin_lock(&inode->i_lock);
  354. bad:
  355. if (xattrs) {
  356. for (i = 0; i < numattr; i++)
  357. kfree(xattrs[i]);
  358. kfree(xattrs);
  359. }
  360. ci->i_xattrs.names_size = 0;
  361. return err;
  362. }
  363. static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
  364. int val_size)
  365. {
  366. /*
  367. * 4 bytes for the length, and additional 4 bytes per each xattr name,
  368. * 4 bytes per each value
  369. */
  370. int size = 4 + ci->i_xattrs.count*(4 + 4) +
  371. ci->i_xattrs.names_size +
  372. ci->i_xattrs.vals_size;
  373. dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
  374. ci->i_xattrs.count, ci->i_xattrs.names_size,
  375. ci->i_xattrs.vals_size);
  376. if (name_size)
  377. size += 4 + 4 + name_size + val_size;
  378. return size;
  379. }
  380. /*
  381. * If there are dirty xattrs, reencode xattrs into the prealloc_blob
  382. * and swap into place.
  383. */
  384. void __ceph_build_xattrs_blob(struct ceph_inode_info *ci)
  385. {
  386. struct rb_node *p;
  387. struct ceph_inode_xattr *xattr = NULL;
  388. void *dest;
  389. dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
  390. if (ci->i_xattrs.dirty) {
  391. int need = __get_required_blob_size(ci, 0, 0);
  392. BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
  393. p = rb_first(&ci->i_xattrs.index);
  394. dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
  395. ceph_encode_32(&dest, ci->i_xattrs.count);
  396. while (p) {
  397. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  398. ceph_encode_32(&dest, xattr->name_len);
  399. memcpy(dest, xattr->name, xattr->name_len);
  400. dest += xattr->name_len;
  401. ceph_encode_32(&dest, xattr->val_len);
  402. memcpy(dest, xattr->val, xattr->val_len);
  403. dest += xattr->val_len;
  404. p = rb_next(p);
  405. }
  406. /* adjust buffer len; it may be larger than we need */
  407. ci->i_xattrs.prealloc_blob->vec.iov_len =
  408. dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
  409. ceph_buffer_put(ci->i_xattrs.blob);
  410. ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
  411. ci->i_xattrs.prealloc_blob = NULL;
  412. ci->i_xattrs.dirty = false;
  413. }
  414. }
  415. ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
  416. size_t size)
  417. {
  418. struct inode *inode = dentry->d_inode;
  419. struct ceph_inode_info *ci = ceph_inode(inode);
  420. struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
  421. int err;
  422. struct ceph_inode_xattr *xattr;
  423. struct ceph_vxattr_cb *vxattr = NULL;
  424. if (!ceph_is_valid_xattr(name))
  425. return -ENODATA;
  426. /* let's see if a virtual xattr was requested */
  427. if (vxattrs)
  428. vxattr = ceph_match_vxattr(vxattrs, name);
  429. spin_lock(&inode->i_lock);
  430. dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
  431. ci->i_xattrs.version, ci->i_xattrs.index_version);
  432. if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
  433. (ci->i_xattrs.index_version >= ci->i_xattrs.version)) {
  434. goto get_xattr;
  435. } else {
  436. spin_unlock(&inode->i_lock);
  437. /* get xattrs from mds (if we don't already have them) */
  438. err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
  439. if (err)
  440. return err;
  441. }
  442. spin_lock(&inode->i_lock);
  443. if (vxattr && vxattr->readonly) {
  444. err = vxattr->getxattr_cb(ci, value, size);
  445. goto out;
  446. }
  447. err = __build_xattrs(inode);
  448. if (err < 0)
  449. goto out;
  450. get_xattr:
  451. err = -ENODATA; /* == ENOATTR */
  452. xattr = __get_xattr(ci, name);
  453. if (!xattr) {
  454. if (vxattr)
  455. err = vxattr->getxattr_cb(ci, value, size);
  456. goto out;
  457. }
  458. err = -ERANGE;
  459. if (size && size < xattr->val_len)
  460. goto out;
  461. err = xattr->val_len;
  462. if (size == 0)
  463. goto out;
  464. memcpy(value, xattr->val, xattr->val_len);
  465. out:
  466. spin_unlock(&inode->i_lock);
  467. return err;
  468. }
  469. ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
  470. {
  471. struct inode *inode = dentry->d_inode;
  472. struct ceph_inode_info *ci = ceph_inode(inode);
  473. struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
  474. u32 vir_namelen = 0;
  475. u32 namelen;
  476. int err;
  477. u32 len;
  478. int i;
  479. spin_lock(&inode->i_lock);
  480. dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
  481. ci->i_xattrs.version, ci->i_xattrs.index_version);
  482. if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
  483. (ci->i_xattrs.index_version > ci->i_xattrs.version)) {
  484. goto list_xattr;
  485. } else {
  486. spin_unlock(&inode->i_lock);
  487. err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
  488. if (err)
  489. return err;
  490. }
  491. spin_lock(&inode->i_lock);
  492. err = __build_xattrs(inode);
  493. if (err < 0)
  494. goto out;
  495. list_xattr:
  496. vir_namelen = 0;
  497. /* include virtual dir xattrs */
  498. if (vxattrs)
  499. for (i = 0; vxattrs[i].name; i++)
  500. vir_namelen += strlen(vxattrs[i].name) + 1;
  501. /* adding 1 byte per each variable due to the null termination */
  502. namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
  503. err = -ERANGE;
  504. if (size && namelen > size)
  505. goto out;
  506. err = namelen;
  507. if (size == 0)
  508. goto out;
  509. names = __copy_xattr_names(ci, names);
  510. /* virtual xattr names, too */
  511. if (vxattrs)
  512. for (i = 0; vxattrs[i].name; i++) {
  513. len = sprintf(names, "%s", vxattrs[i].name);
  514. names += len + 1;
  515. }
  516. out:
  517. spin_unlock(&inode->i_lock);
  518. return err;
  519. }
  520. static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
  521. const char *value, size_t size, int flags)
  522. {
  523. struct ceph_client *client = ceph_client(dentry->d_sb);
  524. struct inode *inode = dentry->d_inode;
  525. struct ceph_inode_info *ci = ceph_inode(inode);
  526. struct inode *parent_inode = dentry->d_parent->d_inode;
  527. struct ceph_mds_request *req;
  528. struct ceph_mds_client *mdsc = &client->mdsc;
  529. int err;
  530. int i, nr_pages;
  531. struct page **pages = NULL;
  532. void *kaddr;
  533. /* copy value into some pages */
  534. nr_pages = calc_pages_for(0, size);
  535. if (nr_pages) {
  536. pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS);
  537. if (!pages)
  538. return -ENOMEM;
  539. err = -ENOMEM;
  540. for (i = 0; i < nr_pages; i++) {
  541. pages[i] = alloc_page(GFP_NOFS);
  542. if (!pages[i]) {
  543. nr_pages = i;
  544. goto out;
  545. }
  546. kaddr = kmap(pages[i]);
  547. memcpy(kaddr, value + i*PAGE_CACHE_SIZE,
  548. min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE));
  549. }
  550. }
  551. dout("setxattr value=%.*s\n", (int)size, value);
  552. /* do request */
  553. req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
  554. USE_AUTH_MDS);
  555. if (IS_ERR(req))
  556. return PTR_ERR(req);
  557. req->r_inode = igrab(inode);
  558. req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
  559. req->r_num_caps = 1;
  560. req->r_args.setxattr.flags = cpu_to_le32(flags);
  561. req->r_path2 = kstrdup(name, GFP_NOFS);
  562. req->r_pages = pages;
  563. req->r_num_pages = nr_pages;
  564. req->r_data_len = size;
  565. dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
  566. err = ceph_mdsc_do_request(mdsc, parent_inode, req);
  567. ceph_mdsc_put_request(req);
  568. dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
  569. out:
  570. if (pages) {
  571. for (i = 0; i < nr_pages; i++)
  572. __free_page(pages[i]);
  573. kfree(pages);
  574. }
  575. return err;
  576. }
  577. int ceph_setxattr(struct dentry *dentry, const char *name,
  578. const void *value, size_t size, int flags)
  579. {
  580. struct inode *inode = dentry->d_inode;
  581. struct ceph_inode_info *ci = ceph_inode(inode);
  582. struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
  583. int err;
  584. int name_len = strlen(name);
  585. int val_len = size;
  586. char *newname = NULL;
  587. char *newval = NULL;
  588. struct ceph_inode_xattr *xattr = NULL;
  589. int issued;
  590. int required_blob_size;
  591. if (ceph_snap(inode) != CEPH_NOSNAP)
  592. return -EROFS;
  593. if (!ceph_is_valid_xattr(name))
  594. return -EOPNOTSUPP;
  595. if (vxattrs) {
  596. struct ceph_vxattr_cb *vxattr =
  597. ceph_match_vxattr(vxattrs, name);
  598. if (vxattr && vxattr->readonly)
  599. return -EOPNOTSUPP;
  600. }
  601. /* preallocate memory for xattr name, value, index node */
  602. err = -ENOMEM;
  603. newname = kmalloc(name_len + 1, GFP_NOFS);
  604. if (!newname)
  605. goto out;
  606. memcpy(newname, name, name_len + 1);
  607. if (val_len) {
  608. newval = kmalloc(val_len + 1, GFP_NOFS);
  609. if (!newval)
  610. goto out;
  611. memcpy(newval, value, val_len);
  612. newval[val_len] = '\0';
  613. }
  614. xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
  615. if (!xattr)
  616. goto out;
  617. spin_lock(&inode->i_lock);
  618. retry:
  619. issued = __ceph_caps_issued(ci, NULL);
  620. if (!(issued & CEPH_CAP_XATTR_EXCL))
  621. goto do_sync;
  622. __build_xattrs(inode);
  623. required_blob_size = __get_required_blob_size(ci, name_len, val_len);
  624. if (!ci->i_xattrs.prealloc_blob ||
  625. required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
  626. struct ceph_buffer *blob = NULL;
  627. spin_unlock(&inode->i_lock);
  628. dout(" preaallocating new blob size=%d\n", required_blob_size);
  629. blob = ceph_buffer_new_alloc(required_blob_size, GFP_NOFS);
  630. if (!blob)
  631. goto out;
  632. spin_lock(&inode->i_lock);
  633. ceph_buffer_put(ci->i_xattrs.prealloc_blob);
  634. ci->i_xattrs.prealloc_blob = blob;
  635. goto retry;
  636. }
  637. dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
  638. err = __set_xattr(ci, newname, name_len, newval,
  639. val_len, 1, 1, 1, &xattr);
  640. __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
  641. ci->i_xattrs.dirty = true;
  642. inode->i_ctime = CURRENT_TIME;
  643. spin_unlock(&inode->i_lock);
  644. return err;
  645. do_sync:
  646. spin_unlock(&inode->i_lock);
  647. err = ceph_sync_setxattr(dentry, name, value, size, flags);
  648. out:
  649. kfree(newname);
  650. kfree(newval);
  651. kfree(xattr);
  652. return err;
  653. }
  654. static int ceph_send_removexattr(struct dentry *dentry, const char *name)
  655. {
  656. struct ceph_client *client = ceph_client(dentry->d_sb);
  657. struct ceph_mds_client *mdsc = &client->mdsc;
  658. struct inode *inode = dentry->d_inode;
  659. struct inode *parent_inode = dentry->d_parent->d_inode;
  660. struct ceph_mds_request *req;
  661. int err;
  662. req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR,
  663. USE_AUTH_MDS);
  664. if (IS_ERR(req))
  665. return PTR_ERR(req);
  666. req->r_inode = igrab(inode);
  667. req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
  668. req->r_num_caps = 1;
  669. req->r_path2 = kstrdup(name, GFP_NOFS);
  670. err = ceph_mdsc_do_request(mdsc, parent_inode, req);
  671. ceph_mdsc_put_request(req);
  672. return err;
  673. }
  674. int ceph_removexattr(struct dentry *dentry, const char *name)
  675. {
  676. struct inode *inode = dentry->d_inode;
  677. struct ceph_inode_info *ci = ceph_inode(inode);
  678. struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
  679. int issued;
  680. int err;
  681. if (ceph_snap(inode) != CEPH_NOSNAP)
  682. return -EROFS;
  683. if (!ceph_is_valid_xattr(name))
  684. return -EOPNOTSUPP;
  685. if (vxattrs) {
  686. struct ceph_vxattr_cb *vxattr =
  687. ceph_match_vxattr(vxattrs, name);
  688. if (vxattr && vxattr->readonly)
  689. return -EOPNOTSUPP;
  690. }
  691. spin_lock(&inode->i_lock);
  692. __build_xattrs(inode);
  693. issued = __ceph_caps_issued(ci, NULL);
  694. dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
  695. if (!(issued & CEPH_CAP_XATTR_EXCL))
  696. goto do_sync;
  697. err = __remove_xattr_by_name(ceph_inode(inode), name);
  698. __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
  699. ci->i_xattrs.dirty = true;
  700. inode->i_ctime = CURRENT_TIME;
  701. spin_unlock(&inode->i_lock);
  702. return err;
  703. do_sync:
  704. spin_unlock(&inode->i_lock);
  705. err = ceph_send_removexattr(dentry, name);
  706. return err;
  707. }