xattr.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/ceph/ceph_debug.h>
  3. #include <linux/ceph/pagelist.h>
  4. #include "super.h"
  5. #include "mds_client.h"
  6. #include <linux/ceph/decode.h>
  7. #include <linux/xattr.h>
  8. #include <linux/security.h>
  9. #include <linux/posix_acl_xattr.h>
  10. #include <linux/slab.h>
  11. #define XATTR_CEPH_PREFIX "ceph."
  12. #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1)
  13. static int __remove_xattr(struct ceph_inode_info *ci,
  14. struct ceph_inode_xattr *xattr);
  15. static bool ceph_is_valid_xattr(const char *name)
  16. {
  17. return !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
  18. !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) ||
  19. !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
  20. !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
  21. }
  22. /*
  23. * These define virtual xattrs exposing the recursive directory
  24. * statistics and layout metadata.
  25. */
  26. struct ceph_vxattr {
  27. char *name;
  28. size_t name_size; /* strlen(name) + 1 (for '\0') */
  29. ssize_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
  30. size_t size);
  31. bool (*exists_cb)(struct ceph_inode_info *ci);
  32. unsigned int flags;
  33. };
  34. #define VXATTR_FLAG_READONLY (1<<0)
  35. #define VXATTR_FLAG_HIDDEN (1<<1)
  36. #define VXATTR_FLAG_RSTAT (1<<2)
  37. /* layouts */
  38. static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci)
  39. {
  40. struct ceph_file_layout *fl = &ci->i_layout;
  41. return (fl->stripe_unit > 0 || fl->stripe_count > 0 ||
  42. fl->object_size > 0 || fl->pool_id >= 0 ||
  43. rcu_dereference_raw(fl->pool_ns) != NULL);
  44. }
  45. static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
  46. size_t size)
  47. {
  48. struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
  49. struct ceph_osd_client *osdc = &fsc->client->osdc;
  50. struct ceph_string *pool_ns;
  51. s64 pool = ci->i_layout.pool_id;
  52. const char *pool_name;
  53. const char *ns_field = " pool_namespace=";
  54. char buf[128];
  55. size_t len, total_len = 0;
  56. ssize_t ret;
  57. pool_ns = ceph_try_get_string(ci->i_layout.pool_ns);
  58. dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode);
  59. down_read(&osdc->lock);
  60. pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
  61. if (pool_name) {
  62. len = snprintf(buf, sizeof(buf),
  63. "stripe_unit=%u stripe_count=%u object_size=%u pool=",
  64. ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
  65. ci->i_layout.object_size);
  66. total_len = len + strlen(pool_name);
  67. } else {
  68. len = snprintf(buf, sizeof(buf),
  69. "stripe_unit=%u stripe_count=%u object_size=%u pool=%lld",
  70. ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
  71. ci->i_layout.object_size, pool);
  72. total_len = len;
  73. }
  74. if (pool_ns)
  75. total_len += strlen(ns_field) + pool_ns->len;
  76. ret = total_len;
  77. if (size >= total_len) {
  78. memcpy(val, buf, len);
  79. ret = len;
  80. if (pool_name) {
  81. len = strlen(pool_name);
  82. memcpy(val + ret, pool_name, len);
  83. ret += len;
  84. }
  85. if (pool_ns) {
  86. len = strlen(ns_field);
  87. memcpy(val + ret, ns_field, len);
  88. ret += len;
  89. memcpy(val + ret, pool_ns->str, pool_ns->len);
  90. ret += pool_ns->len;
  91. }
  92. }
  93. up_read(&osdc->lock);
  94. ceph_put_string(pool_ns);
  95. return ret;
  96. }
  97. /*
  98. * The convention with strings in xattrs is that they should not be NULL
  99. * terminated, since we're returning the length with them. snprintf always
  100. * NULL terminates however, so call it on a temporary buffer and then memcpy
  101. * the result into place.
  102. */
  103. static __printf(3, 4)
  104. int ceph_fmt_xattr(char *val, size_t size, const char *fmt, ...)
  105. {
  106. int ret;
  107. va_list args;
  108. char buf[96]; /* NB: reevaluate size if new vxattrs are added */
  109. va_start(args, fmt);
  110. ret = vsnprintf(buf, size ? sizeof(buf) : 0, fmt, args);
  111. va_end(args);
  112. /* Sanity check */
  113. if (size && ret + 1 > sizeof(buf)) {
  114. WARN_ONCE(true, "Returned length too big (%d)", ret);
  115. return -E2BIG;
  116. }
  117. if (ret <= size)
  118. memcpy(val, buf, ret);
  119. return ret;
  120. }
  121. static ssize_t ceph_vxattrcb_layout_stripe_unit(struct ceph_inode_info *ci,
  122. char *val, size_t size)
  123. {
  124. return ceph_fmt_xattr(val, size, "%u", ci->i_layout.stripe_unit);
  125. }
  126. static ssize_t ceph_vxattrcb_layout_stripe_count(struct ceph_inode_info *ci,
  127. char *val, size_t size)
  128. {
  129. return ceph_fmt_xattr(val, size, "%u", ci->i_layout.stripe_count);
  130. }
  131. static ssize_t ceph_vxattrcb_layout_object_size(struct ceph_inode_info *ci,
  132. char *val, size_t size)
  133. {
  134. return ceph_fmt_xattr(val, size, "%u", ci->i_layout.object_size);
  135. }
  136. static ssize_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci,
  137. char *val, size_t size)
  138. {
  139. ssize_t ret;
  140. struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
  141. struct ceph_osd_client *osdc = &fsc->client->osdc;
  142. s64 pool = ci->i_layout.pool_id;
  143. const char *pool_name;
  144. down_read(&osdc->lock);
  145. pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
  146. if (pool_name) {
  147. ret = strlen(pool_name);
  148. if (ret <= size)
  149. memcpy(val, pool_name, ret);
  150. } else {
  151. ret = ceph_fmt_xattr(val, size, "%lld", pool);
  152. }
  153. up_read(&osdc->lock);
  154. return ret;
  155. }
  156. static ssize_t ceph_vxattrcb_layout_pool_namespace(struct ceph_inode_info *ci,
  157. char *val, size_t size)
  158. {
  159. ssize_t ret = 0;
  160. struct ceph_string *ns = ceph_try_get_string(ci->i_layout.pool_ns);
  161. if (ns) {
  162. ret = ns->len;
  163. if (ret <= size)
  164. memcpy(val, ns->str, ret);
  165. ceph_put_string(ns);
  166. }
  167. return ret;
  168. }
  169. /* directories */
  170. static ssize_t ceph_vxattrcb_dir_entries(struct ceph_inode_info *ci, char *val,
  171. size_t size)
  172. {
  173. return ceph_fmt_xattr(val, size, "%lld", ci->i_files + ci->i_subdirs);
  174. }
  175. static ssize_t ceph_vxattrcb_dir_files(struct ceph_inode_info *ci, char *val,
  176. size_t size)
  177. {
  178. return ceph_fmt_xattr(val, size, "%lld", ci->i_files);
  179. }
  180. static ssize_t ceph_vxattrcb_dir_subdirs(struct ceph_inode_info *ci, char *val,
  181. size_t size)
  182. {
  183. return ceph_fmt_xattr(val, size, "%lld", ci->i_subdirs);
  184. }
  185. static ssize_t ceph_vxattrcb_dir_rentries(struct ceph_inode_info *ci, char *val,
  186. size_t size)
  187. {
  188. return ceph_fmt_xattr(val, size, "%lld",
  189. ci->i_rfiles + ci->i_rsubdirs);
  190. }
  191. static ssize_t ceph_vxattrcb_dir_rfiles(struct ceph_inode_info *ci, char *val,
  192. size_t size)
  193. {
  194. return ceph_fmt_xattr(val, size, "%lld", ci->i_rfiles);
  195. }
  196. static ssize_t ceph_vxattrcb_dir_rsubdirs(struct ceph_inode_info *ci, char *val,
  197. size_t size)
  198. {
  199. return ceph_fmt_xattr(val, size, "%lld", ci->i_rsubdirs);
  200. }
  201. static ssize_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info *ci, char *val,
  202. size_t size)
  203. {
  204. return ceph_fmt_xattr(val, size, "%lld", ci->i_rbytes);
  205. }
  206. static ssize_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
  207. size_t size)
  208. {
  209. return ceph_fmt_xattr(val, size, "%lld.%09ld", ci->i_rctime.tv_sec,
  210. ci->i_rctime.tv_nsec);
  211. }
  212. /* dir pin */
  213. static bool ceph_vxattrcb_dir_pin_exists(struct ceph_inode_info *ci)
  214. {
  215. return ci->i_dir_pin != -ENODATA;
  216. }
  217. static ssize_t ceph_vxattrcb_dir_pin(struct ceph_inode_info *ci, char *val,
  218. size_t size)
  219. {
  220. return ceph_fmt_xattr(val, size, "%d", (int)ci->i_dir_pin);
  221. }
  222. /* quotas */
  223. static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
  224. {
  225. bool ret = false;
  226. spin_lock(&ci->i_ceph_lock);
  227. if ((ci->i_max_files || ci->i_max_bytes) &&
  228. ci->i_vino.snap == CEPH_NOSNAP &&
  229. ci->i_snap_realm &&
  230. ci->i_snap_realm->ino == ci->i_vino.ino)
  231. ret = true;
  232. spin_unlock(&ci->i_ceph_lock);
  233. return ret;
  234. }
  235. static ssize_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val,
  236. size_t size)
  237. {
  238. return ceph_fmt_xattr(val, size, "max_bytes=%llu max_files=%llu",
  239. ci->i_max_bytes, ci->i_max_files);
  240. }
  241. static ssize_t ceph_vxattrcb_quota_max_bytes(struct ceph_inode_info *ci,
  242. char *val, size_t size)
  243. {
  244. return ceph_fmt_xattr(val, size, "%llu", ci->i_max_bytes);
  245. }
  246. static ssize_t ceph_vxattrcb_quota_max_files(struct ceph_inode_info *ci,
  247. char *val, size_t size)
  248. {
  249. return ceph_fmt_xattr(val, size, "%llu", ci->i_max_files);
  250. }
  251. /* snapshots */
  252. static bool ceph_vxattrcb_snap_btime_exists(struct ceph_inode_info *ci)
  253. {
  254. return (ci->i_snap_btime.tv_sec != 0 || ci->i_snap_btime.tv_nsec != 0);
  255. }
  256. static ssize_t ceph_vxattrcb_snap_btime(struct ceph_inode_info *ci, char *val,
  257. size_t size)
  258. {
  259. return ceph_fmt_xattr(val, size, "%lld.%09ld", ci->i_snap_btime.tv_sec,
  260. ci->i_snap_btime.tv_nsec);
  261. }
  262. #define CEPH_XATTR_NAME(_type, _name) XATTR_CEPH_PREFIX #_type "." #_name
  263. #define CEPH_XATTR_NAME2(_type, _name, _name2) \
  264. XATTR_CEPH_PREFIX #_type "." #_name "." #_name2
  265. #define XATTR_NAME_CEPH(_type, _name, _flags) \
  266. { \
  267. .name = CEPH_XATTR_NAME(_type, _name), \
  268. .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
  269. .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
  270. .exists_cb = NULL, \
  271. .flags = (VXATTR_FLAG_READONLY | _flags), \
  272. }
  273. #define XATTR_RSTAT_FIELD(_type, _name) \
  274. XATTR_NAME_CEPH(_type, _name, VXATTR_FLAG_RSTAT)
  275. #define XATTR_LAYOUT_FIELD(_type, _name, _field) \
  276. { \
  277. .name = CEPH_XATTR_NAME2(_type, _name, _field), \
  278. .name_size = sizeof (CEPH_XATTR_NAME2(_type, _name, _field)), \
  279. .getxattr_cb = ceph_vxattrcb_ ## _name ## _ ## _field, \
  280. .exists_cb = ceph_vxattrcb_layout_exists, \
  281. .flags = VXATTR_FLAG_HIDDEN, \
  282. }
  283. #define XATTR_QUOTA_FIELD(_type, _name) \
  284. { \
  285. .name = CEPH_XATTR_NAME(_type, _name), \
  286. .name_size = sizeof(CEPH_XATTR_NAME(_type, _name)), \
  287. .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
  288. .exists_cb = ceph_vxattrcb_quota_exists, \
  289. .flags = VXATTR_FLAG_HIDDEN, \
  290. }
  291. static struct ceph_vxattr ceph_dir_vxattrs[] = {
  292. {
  293. .name = "ceph.dir.layout",
  294. .name_size = sizeof("ceph.dir.layout"),
  295. .getxattr_cb = ceph_vxattrcb_layout,
  296. .exists_cb = ceph_vxattrcb_layout_exists,
  297. .flags = VXATTR_FLAG_HIDDEN,
  298. },
  299. XATTR_LAYOUT_FIELD(dir, layout, stripe_unit),
  300. XATTR_LAYOUT_FIELD(dir, layout, stripe_count),
  301. XATTR_LAYOUT_FIELD(dir, layout, object_size),
  302. XATTR_LAYOUT_FIELD(dir, layout, pool),
  303. XATTR_LAYOUT_FIELD(dir, layout, pool_namespace),
  304. XATTR_NAME_CEPH(dir, entries, 0),
  305. XATTR_NAME_CEPH(dir, files, 0),
  306. XATTR_NAME_CEPH(dir, subdirs, 0),
  307. XATTR_RSTAT_FIELD(dir, rentries),
  308. XATTR_RSTAT_FIELD(dir, rfiles),
  309. XATTR_RSTAT_FIELD(dir, rsubdirs),
  310. XATTR_RSTAT_FIELD(dir, rbytes),
  311. XATTR_RSTAT_FIELD(dir, rctime),
  312. {
  313. .name = "ceph.dir.pin",
  314. .name_size = sizeof("ceph.dir.pin"),
  315. .getxattr_cb = ceph_vxattrcb_dir_pin,
  316. .exists_cb = ceph_vxattrcb_dir_pin_exists,
  317. .flags = VXATTR_FLAG_HIDDEN,
  318. },
  319. {
  320. .name = "ceph.quota",
  321. .name_size = sizeof("ceph.quota"),
  322. .getxattr_cb = ceph_vxattrcb_quota,
  323. .exists_cb = ceph_vxattrcb_quota_exists,
  324. .flags = VXATTR_FLAG_HIDDEN,
  325. },
  326. XATTR_QUOTA_FIELD(quota, max_bytes),
  327. XATTR_QUOTA_FIELD(quota, max_files),
  328. {
  329. .name = "ceph.snap.btime",
  330. .name_size = sizeof("ceph.snap.btime"),
  331. .getxattr_cb = ceph_vxattrcb_snap_btime,
  332. .exists_cb = ceph_vxattrcb_snap_btime_exists,
  333. .flags = VXATTR_FLAG_READONLY,
  334. },
  335. { .name = NULL, 0 } /* Required table terminator */
  336. };
  337. /* files */
  338. static struct ceph_vxattr ceph_file_vxattrs[] = {
  339. {
  340. .name = "ceph.file.layout",
  341. .name_size = sizeof("ceph.file.layout"),
  342. .getxattr_cb = ceph_vxattrcb_layout,
  343. .exists_cb = ceph_vxattrcb_layout_exists,
  344. .flags = VXATTR_FLAG_HIDDEN,
  345. },
  346. XATTR_LAYOUT_FIELD(file, layout, stripe_unit),
  347. XATTR_LAYOUT_FIELD(file, layout, stripe_count),
  348. XATTR_LAYOUT_FIELD(file, layout, object_size),
  349. XATTR_LAYOUT_FIELD(file, layout, pool),
  350. XATTR_LAYOUT_FIELD(file, layout, pool_namespace),
  351. {
  352. .name = "ceph.snap.btime",
  353. .name_size = sizeof("ceph.snap.btime"),
  354. .getxattr_cb = ceph_vxattrcb_snap_btime,
  355. .exists_cb = ceph_vxattrcb_snap_btime_exists,
  356. .flags = VXATTR_FLAG_READONLY,
  357. },
  358. { .name = NULL, 0 } /* Required table terminator */
  359. };
  360. static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
  361. {
  362. if (S_ISDIR(inode->i_mode))
  363. return ceph_dir_vxattrs;
  364. else if (S_ISREG(inode->i_mode))
  365. return ceph_file_vxattrs;
  366. return NULL;
  367. }
  368. static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
  369. const char *name)
  370. {
  371. struct ceph_vxattr *vxattr = ceph_inode_vxattrs(inode);
  372. if (vxattr) {
  373. while (vxattr->name) {
  374. if (!strcmp(vxattr->name, name))
  375. return vxattr;
  376. vxattr++;
  377. }
  378. }
  379. return NULL;
  380. }
  381. static int __set_xattr(struct ceph_inode_info *ci,
  382. const char *name, int name_len,
  383. const char *val, int val_len,
  384. int flags, int update_xattr,
  385. struct ceph_inode_xattr **newxattr)
  386. {
  387. struct rb_node **p;
  388. struct rb_node *parent = NULL;
  389. struct ceph_inode_xattr *xattr = NULL;
  390. int c;
  391. int new = 0;
  392. p = &ci->i_xattrs.index.rb_node;
  393. while (*p) {
  394. parent = *p;
  395. xattr = rb_entry(parent, struct ceph_inode_xattr, node);
  396. c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
  397. if (c < 0)
  398. p = &(*p)->rb_left;
  399. else if (c > 0)
  400. p = &(*p)->rb_right;
  401. else {
  402. if (name_len == xattr->name_len)
  403. break;
  404. else if (name_len < xattr->name_len)
  405. p = &(*p)->rb_left;
  406. else
  407. p = &(*p)->rb_right;
  408. }
  409. xattr = NULL;
  410. }
  411. if (update_xattr) {
  412. int err = 0;
  413. if (xattr && (flags & XATTR_CREATE))
  414. err = -EEXIST;
  415. else if (!xattr && (flags & XATTR_REPLACE))
  416. err = -ENODATA;
  417. if (err) {
  418. kfree(name);
  419. kfree(val);
  420. kfree(*newxattr);
  421. return err;
  422. }
  423. if (update_xattr < 0) {
  424. if (xattr)
  425. __remove_xattr(ci, xattr);
  426. kfree(name);
  427. kfree(*newxattr);
  428. return 0;
  429. }
  430. }
  431. if (!xattr) {
  432. new = 1;
  433. xattr = *newxattr;
  434. xattr->name = name;
  435. xattr->name_len = name_len;
  436. xattr->should_free_name = update_xattr;
  437. ci->i_xattrs.count++;
  438. dout("__set_xattr count=%d\n", ci->i_xattrs.count);
  439. } else {
  440. kfree(*newxattr);
  441. *newxattr = NULL;
  442. if (xattr->should_free_val)
  443. kfree(xattr->val);
  444. if (update_xattr) {
  445. kfree(name);
  446. name = xattr->name;
  447. }
  448. ci->i_xattrs.names_size -= xattr->name_len;
  449. ci->i_xattrs.vals_size -= xattr->val_len;
  450. }
  451. ci->i_xattrs.names_size += name_len;
  452. ci->i_xattrs.vals_size += val_len;
  453. if (val)
  454. xattr->val = val;
  455. else
  456. xattr->val = "";
  457. xattr->val_len = val_len;
  458. xattr->dirty = update_xattr;
  459. xattr->should_free_val = (val && update_xattr);
  460. if (new) {
  461. rb_link_node(&xattr->node, parent, p);
  462. rb_insert_color(&xattr->node, &ci->i_xattrs.index);
  463. dout("__set_xattr_val p=%p\n", p);
  464. }
  465. dout("__set_xattr_val added %llx.%llx xattr %p %.*s=%.*s\n",
  466. ceph_vinop(&ci->vfs_inode), xattr, name_len, name, val_len, val);
  467. return 0;
  468. }
  469. static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
  470. const char *name)
  471. {
  472. struct rb_node **p;
  473. struct rb_node *parent = NULL;
  474. struct ceph_inode_xattr *xattr = NULL;
  475. int name_len = strlen(name);
  476. int c;
  477. p = &ci->i_xattrs.index.rb_node;
  478. while (*p) {
  479. parent = *p;
  480. xattr = rb_entry(parent, struct ceph_inode_xattr, node);
  481. c = strncmp(name, xattr->name, xattr->name_len);
  482. if (c == 0 && name_len > xattr->name_len)
  483. c = 1;
  484. if (c < 0)
  485. p = &(*p)->rb_left;
  486. else if (c > 0)
  487. p = &(*p)->rb_right;
  488. else {
  489. dout("__get_xattr %s: found %.*s\n", name,
  490. xattr->val_len, xattr->val);
  491. return xattr;
  492. }
  493. }
  494. dout("__get_xattr %s: not found\n", name);
  495. return NULL;
  496. }
  497. static void __free_xattr(struct ceph_inode_xattr *xattr)
  498. {
  499. BUG_ON(!xattr);
  500. if (xattr->should_free_name)
  501. kfree(xattr->name);
  502. if (xattr->should_free_val)
  503. kfree(xattr->val);
  504. kfree(xattr);
  505. }
  506. static int __remove_xattr(struct ceph_inode_info *ci,
  507. struct ceph_inode_xattr *xattr)
  508. {
  509. if (!xattr)
  510. return -ENODATA;
  511. rb_erase(&xattr->node, &ci->i_xattrs.index);
  512. if (xattr->should_free_name)
  513. kfree(xattr->name);
  514. if (xattr->should_free_val)
  515. kfree(xattr->val);
  516. ci->i_xattrs.names_size -= xattr->name_len;
  517. ci->i_xattrs.vals_size -= xattr->val_len;
  518. ci->i_xattrs.count--;
  519. kfree(xattr);
  520. return 0;
  521. }
  522. static char *__copy_xattr_names(struct ceph_inode_info *ci,
  523. char *dest)
  524. {
  525. struct rb_node *p;
  526. struct ceph_inode_xattr *xattr = NULL;
  527. p = rb_first(&ci->i_xattrs.index);
  528. dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
  529. while (p) {
  530. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  531. memcpy(dest, xattr->name, xattr->name_len);
  532. dest[xattr->name_len] = '\0';
  533. dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
  534. xattr->name_len, ci->i_xattrs.names_size);
  535. dest += xattr->name_len + 1;
  536. p = rb_next(p);
  537. }
  538. return dest;
  539. }
  540. void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
  541. {
  542. struct rb_node *p, *tmp;
  543. struct ceph_inode_xattr *xattr = NULL;
  544. p = rb_first(&ci->i_xattrs.index);
  545. dout("__ceph_destroy_xattrs p=%p\n", p);
  546. while (p) {
  547. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  548. tmp = p;
  549. p = rb_next(tmp);
  550. dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
  551. xattr->name_len, xattr->name);
  552. rb_erase(tmp, &ci->i_xattrs.index);
  553. __free_xattr(xattr);
  554. }
  555. ci->i_xattrs.names_size = 0;
  556. ci->i_xattrs.vals_size = 0;
  557. ci->i_xattrs.index_version = 0;
  558. ci->i_xattrs.count = 0;
  559. ci->i_xattrs.index = RB_ROOT;
  560. }
  561. static int __build_xattrs(struct inode *inode)
  562. __releases(ci->i_ceph_lock)
  563. __acquires(ci->i_ceph_lock)
  564. {
  565. u32 namelen;
  566. u32 numattr = 0;
  567. void *p, *end;
  568. u32 len;
  569. const char *name, *val;
  570. struct ceph_inode_info *ci = ceph_inode(inode);
  571. u64 xattr_version;
  572. struct ceph_inode_xattr **xattrs = NULL;
  573. int err = 0;
  574. int i;
  575. dout("__build_xattrs() len=%d\n",
  576. ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
  577. if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
  578. return 0; /* already built */
  579. __ceph_destroy_xattrs(ci);
  580. start:
  581. /* updated internal xattr rb tree */
  582. if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
  583. p = ci->i_xattrs.blob->vec.iov_base;
  584. end = p + ci->i_xattrs.blob->vec.iov_len;
  585. ceph_decode_32_safe(&p, end, numattr, bad);
  586. xattr_version = ci->i_xattrs.version;
  587. spin_unlock(&ci->i_ceph_lock);
  588. xattrs = kcalloc(numattr, sizeof(struct ceph_inode_xattr *),
  589. GFP_NOFS);
  590. err = -ENOMEM;
  591. if (!xattrs)
  592. goto bad_lock;
  593. for (i = 0; i < numattr; i++) {
  594. xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
  595. GFP_NOFS);
  596. if (!xattrs[i])
  597. goto bad_lock;
  598. }
  599. spin_lock(&ci->i_ceph_lock);
  600. if (ci->i_xattrs.version != xattr_version) {
  601. /* lost a race, retry */
  602. for (i = 0; i < numattr; i++)
  603. kfree(xattrs[i]);
  604. kfree(xattrs);
  605. xattrs = NULL;
  606. goto start;
  607. }
  608. err = -EIO;
  609. while (numattr--) {
  610. ceph_decode_32_safe(&p, end, len, bad);
  611. namelen = len;
  612. name = p;
  613. p += len;
  614. ceph_decode_32_safe(&p, end, len, bad);
  615. val = p;
  616. p += len;
  617. err = __set_xattr(ci, name, namelen, val, len,
  618. 0, 0, &xattrs[numattr]);
  619. if (err < 0)
  620. goto bad;
  621. }
  622. kfree(xattrs);
  623. }
  624. ci->i_xattrs.index_version = ci->i_xattrs.version;
  625. ci->i_xattrs.dirty = false;
  626. return err;
  627. bad_lock:
  628. spin_lock(&ci->i_ceph_lock);
  629. bad:
  630. if (xattrs) {
  631. for (i = 0; i < numattr; i++)
  632. kfree(xattrs[i]);
  633. kfree(xattrs);
  634. }
  635. ci->i_xattrs.names_size = 0;
  636. return err;
  637. }
  638. static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
  639. int val_size)
  640. {
  641. /*
  642. * 4 bytes for the length, and additional 4 bytes per each xattr name,
  643. * 4 bytes per each value
  644. */
  645. int size = 4 + ci->i_xattrs.count*(4 + 4) +
  646. ci->i_xattrs.names_size +
  647. ci->i_xattrs.vals_size;
  648. dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
  649. ci->i_xattrs.count, ci->i_xattrs.names_size,
  650. ci->i_xattrs.vals_size);
  651. if (name_size)
  652. size += 4 + 4 + name_size + val_size;
  653. return size;
  654. }
  655. /*
  656. * If there are dirty xattrs, reencode xattrs into the prealloc_blob
  657. * and swap into place. It returns the old i_xattrs.blob (or NULL) so
  658. * that it can be freed by the caller as the i_ceph_lock is likely to be
  659. * held.
  660. */
  661. struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci)
  662. {
  663. struct rb_node *p;
  664. struct ceph_inode_xattr *xattr = NULL;
  665. struct ceph_buffer *old_blob = NULL;
  666. void *dest;
  667. dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
  668. if (ci->i_xattrs.dirty) {
  669. int need = __get_required_blob_size(ci, 0, 0);
  670. BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
  671. p = rb_first(&ci->i_xattrs.index);
  672. dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
  673. ceph_encode_32(&dest, ci->i_xattrs.count);
  674. while (p) {
  675. xattr = rb_entry(p, struct ceph_inode_xattr, node);
  676. ceph_encode_32(&dest, xattr->name_len);
  677. memcpy(dest, xattr->name, xattr->name_len);
  678. dest += xattr->name_len;
  679. ceph_encode_32(&dest, xattr->val_len);
  680. memcpy(dest, xattr->val, xattr->val_len);
  681. dest += xattr->val_len;
  682. p = rb_next(p);
  683. }
  684. /* adjust buffer len; it may be larger than we need */
  685. ci->i_xattrs.prealloc_blob->vec.iov_len =
  686. dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
  687. if (ci->i_xattrs.blob)
  688. old_blob = ci->i_xattrs.blob;
  689. ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
  690. ci->i_xattrs.prealloc_blob = NULL;
  691. ci->i_xattrs.dirty = false;
  692. ci->i_xattrs.version++;
  693. }
  694. return old_blob;
  695. }
  696. static inline int __get_request_mask(struct inode *in) {
  697. struct ceph_mds_request *req = current->journal_info;
  698. int mask = 0;
  699. if (req && req->r_target_inode == in) {
  700. if (req->r_op == CEPH_MDS_OP_LOOKUP ||
  701. req->r_op == CEPH_MDS_OP_LOOKUPINO ||
  702. req->r_op == CEPH_MDS_OP_LOOKUPPARENT ||
  703. req->r_op == CEPH_MDS_OP_GETATTR) {
  704. mask = le32_to_cpu(req->r_args.getattr.mask);
  705. } else if (req->r_op == CEPH_MDS_OP_OPEN ||
  706. req->r_op == CEPH_MDS_OP_CREATE) {
  707. mask = le32_to_cpu(req->r_args.open.mask);
  708. }
  709. }
  710. return mask;
  711. }
  712. ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
  713. size_t size)
  714. {
  715. struct ceph_inode_info *ci = ceph_inode(inode);
  716. struct ceph_inode_xattr *xattr;
  717. struct ceph_vxattr *vxattr = NULL;
  718. int req_mask;
  719. ssize_t err;
  720. /* let's see if a virtual xattr was requested */
  721. vxattr = ceph_match_vxattr(inode, name);
  722. if (vxattr) {
  723. int mask = 0;
  724. if (vxattr->flags & VXATTR_FLAG_RSTAT)
  725. mask |= CEPH_STAT_RSTAT;
  726. err = ceph_do_getattr(inode, mask, true);
  727. if (err)
  728. return err;
  729. err = -ENODATA;
  730. if (!(vxattr->exists_cb && !vxattr->exists_cb(ci))) {
  731. err = vxattr->getxattr_cb(ci, value, size);
  732. if (size && size < err)
  733. err = -ERANGE;
  734. }
  735. return err;
  736. }
  737. req_mask = __get_request_mask(inode);
  738. spin_lock(&ci->i_ceph_lock);
  739. dout("getxattr %p name '%s' ver=%lld index_ver=%lld\n", inode, name,
  740. ci->i_xattrs.version, ci->i_xattrs.index_version);
  741. if (ci->i_xattrs.version == 0 ||
  742. !((req_mask & CEPH_CAP_XATTR_SHARED) ||
  743. __ceph_caps_issued_mask_metric(ci, CEPH_CAP_XATTR_SHARED, 1))) {
  744. spin_unlock(&ci->i_ceph_lock);
  745. /* security module gets xattr while filling trace */
  746. if (current->journal_info) {
  747. pr_warn_ratelimited("sync getxattr %p "
  748. "during filling trace\n", inode);
  749. return -EBUSY;
  750. }
  751. /* get xattrs from mds (if we don't already have them) */
  752. err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
  753. if (err)
  754. return err;
  755. spin_lock(&ci->i_ceph_lock);
  756. }
  757. err = __build_xattrs(inode);
  758. if (err < 0)
  759. goto out;
  760. err = -ENODATA; /* == ENOATTR */
  761. xattr = __get_xattr(ci, name);
  762. if (!xattr)
  763. goto out;
  764. err = -ERANGE;
  765. if (size && size < xattr->val_len)
  766. goto out;
  767. err = xattr->val_len;
  768. if (size == 0)
  769. goto out;
  770. memcpy(value, xattr->val, xattr->val_len);
  771. if (current->journal_info &&
  772. !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
  773. security_ismaclabel(name + XATTR_SECURITY_PREFIX_LEN))
  774. ci->i_ceph_flags |= CEPH_I_SEC_INITED;
  775. out:
  776. spin_unlock(&ci->i_ceph_lock);
  777. return err;
  778. }
  779. ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
  780. {
  781. struct inode *inode = d_inode(dentry);
  782. struct ceph_inode_info *ci = ceph_inode(inode);
  783. bool len_only = (size == 0);
  784. u32 namelen;
  785. int err;
  786. spin_lock(&ci->i_ceph_lock);
  787. dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
  788. ci->i_xattrs.version, ci->i_xattrs.index_version);
  789. if (ci->i_xattrs.version == 0 ||
  790. !__ceph_caps_issued_mask_metric(ci, CEPH_CAP_XATTR_SHARED, 1)) {
  791. spin_unlock(&ci->i_ceph_lock);
  792. err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
  793. if (err)
  794. return err;
  795. spin_lock(&ci->i_ceph_lock);
  796. }
  797. err = __build_xattrs(inode);
  798. if (err < 0)
  799. goto out;
  800. /* add 1 byte for each xattr due to the null termination */
  801. namelen = ci->i_xattrs.names_size + ci->i_xattrs.count;
  802. if (!len_only) {
  803. if (namelen > size) {
  804. err = -ERANGE;
  805. goto out;
  806. }
  807. names = __copy_xattr_names(ci, names);
  808. size -= namelen;
  809. }
  810. err = namelen;
  811. out:
  812. spin_unlock(&ci->i_ceph_lock);
  813. return err;
  814. }
  815. static int ceph_sync_setxattr(struct inode *inode, const char *name,
  816. const char *value, size_t size, int flags)
  817. {
  818. struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
  819. struct ceph_inode_info *ci = ceph_inode(inode);
  820. struct ceph_mds_request *req;
  821. struct ceph_mds_client *mdsc = fsc->mdsc;
  822. struct ceph_pagelist *pagelist = NULL;
  823. int op = CEPH_MDS_OP_SETXATTR;
  824. int err;
  825. if (size > 0) {
  826. /* copy value into pagelist */
  827. pagelist = ceph_pagelist_alloc(GFP_NOFS);
  828. if (!pagelist)
  829. return -ENOMEM;
  830. err = ceph_pagelist_append(pagelist, value, size);
  831. if (err)
  832. goto out;
  833. } else if (!value) {
  834. if (flags & CEPH_XATTR_REPLACE)
  835. op = CEPH_MDS_OP_RMXATTR;
  836. else
  837. flags |= CEPH_XATTR_REMOVE;
  838. }
  839. dout("setxattr value=%.*s\n", (int)size, value);
  840. /* do request */
  841. req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
  842. if (IS_ERR(req)) {
  843. err = PTR_ERR(req);
  844. goto out;
  845. }
  846. req->r_path2 = kstrdup(name, GFP_NOFS);
  847. if (!req->r_path2) {
  848. ceph_mdsc_put_request(req);
  849. err = -ENOMEM;
  850. goto out;
  851. }
  852. if (op == CEPH_MDS_OP_SETXATTR) {
  853. req->r_args.setxattr.flags = cpu_to_le32(flags);
  854. req->r_pagelist = pagelist;
  855. pagelist = NULL;
  856. }
  857. req->r_inode = inode;
  858. ihold(inode);
  859. req->r_num_caps = 1;
  860. req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
  861. dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
  862. err = ceph_mdsc_do_request(mdsc, NULL, req);
  863. ceph_mdsc_put_request(req);
  864. dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
  865. out:
  866. if (pagelist)
  867. ceph_pagelist_release(pagelist);
  868. return err;
  869. }
  870. int __ceph_setxattr(struct inode *inode, const char *name,
  871. const void *value, size_t size, int flags)
  872. {
  873. struct ceph_vxattr *vxattr;
  874. struct ceph_inode_info *ci = ceph_inode(inode);
  875. struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
  876. struct ceph_cap_flush *prealloc_cf = NULL;
  877. struct ceph_buffer *old_blob = NULL;
  878. int issued;
  879. int err;
  880. int dirty = 0;
  881. int name_len = strlen(name);
  882. int val_len = size;
  883. char *newname = NULL;
  884. char *newval = NULL;
  885. struct ceph_inode_xattr *xattr = NULL;
  886. int required_blob_size;
  887. bool check_realm = false;
  888. bool lock_snap_rwsem = false;
  889. if (ceph_snap(inode) != CEPH_NOSNAP)
  890. return -EROFS;
  891. vxattr = ceph_match_vxattr(inode, name);
  892. if (vxattr) {
  893. if (vxattr->flags & VXATTR_FLAG_READONLY)
  894. return -EOPNOTSUPP;
  895. if (value && !strncmp(vxattr->name, "ceph.quota", 10))
  896. check_realm = true;
  897. }
  898. /* pass any unhandled ceph.* xattrs through to the MDS */
  899. if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
  900. goto do_sync_unlocked;
  901. /* preallocate memory for xattr name, value, index node */
  902. err = -ENOMEM;
  903. newname = kmemdup(name, name_len + 1, GFP_NOFS);
  904. if (!newname)
  905. goto out;
  906. if (val_len) {
  907. newval = kmemdup(value, val_len, GFP_NOFS);
  908. if (!newval)
  909. goto out;
  910. }
  911. xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
  912. if (!xattr)
  913. goto out;
  914. prealloc_cf = ceph_alloc_cap_flush();
  915. if (!prealloc_cf)
  916. goto out;
  917. spin_lock(&ci->i_ceph_lock);
  918. retry:
  919. issued = __ceph_caps_issued(ci, NULL);
  920. if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))
  921. goto do_sync;
  922. if (!lock_snap_rwsem && !ci->i_head_snapc) {
  923. lock_snap_rwsem = true;
  924. if (!down_read_trylock(&mdsc->snap_rwsem)) {
  925. spin_unlock(&ci->i_ceph_lock);
  926. down_read(&mdsc->snap_rwsem);
  927. spin_lock(&ci->i_ceph_lock);
  928. goto retry;
  929. }
  930. }
  931. dout("setxattr %p name '%s' issued %s\n", inode, name,
  932. ceph_cap_string(issued));
  933. __build_xattrs(inode);
  934. required_blob_size = __get_required_blob_size(ci, name_len, val_len);
  935. if (!ci->i_xattrs.prealloc_blob ||
  936. required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
  937. struct ceph_buffer *blob;
  938. spin_unlock(&ci->i_ceph_lock);
  939. ceph_buffer_put(old_blob); /* Shouldn't be required */
  940. dout(" pre-allocating new blob size=%d\n", required_blob_size);
  941. blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
  942. if (!blob)
  943. goto do_sync_unlocked;
  944. spin_lock(&ci->i_ceph_lock);
  945. /* prealloc_blob can't be released while holding i_ceph_lock */
  946. if (ci->i_xattrs.prealloc_blob)
  947. old_blob = ci->i_xattrs.prealloc_blob;
  948. ci->i_xattrs.prealloc_blob = blob;
  949. goto retry;
  950. }
  951. err = __set_xattr(ci, newname, name_len, newval, val_len,
  952. flags, value ? 1 : -1, &xattr);
  953. if (!err) {
  954. dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL,
  955. &prealloc_cf);
  956. ci->i_xattrs.dirty = true;
  957. inode->i_ctime = current_time(inode);
  958. }
  959. spin_unlock(&ci->i_ceph_lock);
  960. ceph_buffer_put(old_blob);
  961. if (lock_snap_rwsem)
  962. up_read(&mdsc->snap_rwsem);
  963. if (dirty)
  964. __mark_inode_dirty(inode, dirty);
  965. ceph_free_cap_flush(prealloc_cf);
  966. return err;
  967. do_sync:
  968. spin_unlock(&ci->i_ceph_lock);
  969. do_sync_unlocked:
  970. if (lock_snap_rwsem)
  971. up_read(&mdsc->snap_rwsem);
  972. /* security module set xattr while filling trace */
  973. if (current->journal_info) {
  974. pr_warn_ratelimited("sync setxattr %p "
  975. "during filling trace\n", inode);
  976. err = -EBUSY;
  977. } else {
  978. err = ceph_sync_setxattr(inode, name, value, size, flags);
  979. if (err >= 0 && check_realm) {
  980. /* check if snaprealm was created for quota inode */
  981. spin_lock(&ci->i_ceph_lock);
  982. if ((ci->i_max_files || ci->i_max_bytes) &&
  983. !(ci->i_snap_realm &&
  984. ci->i_snap_realm->ino == ci->i_vino.ino))
  985. err = -EOPNOTSUPP;
  986. spin_unlock(&ci->i_ceph_lock);
  987. }
  988. }
  989. out:
  990. ceph_free_cap_flush(prealloc_cf);
  991. kfree(newname);
  992. kfree(newval);
  993. kfree(xattr);
  994. return err;
  995. }
  996. static int ceph_get_xattr_handler(const struct xattr_handler *handler,
  997. struct dentry *dentry, struct inode *inode,
  998. const char *name, void *value, size_t size,
  999. int flags)
  1000. {
  1001. if (!ceph_is_valid_xattr(name))
  1002. return -EOPNOTSUPP;
  1003. return __ceph_getxattr(inode, name, value, size);
  1004. }
  1005. static int ceph_set_xattr_handler(const struct xattr_handler *handler,
  1006. struct dentry *unused, struct inode *inode,
  1007. const char *name, const void *value,
  1008. size_t size, int flags)
  1009. {
  1010. if (!ceph_is_valid_xattr(name))
  1011. return -EOPNOTSUPP;
  1012. return __ceph_setxattr(inode, name, value, size, flags);
  1013. }
  1014. static const struct xattr_handler ceph_other_xattr_handler = {
  1015. .prefix = "", /* match any name => handlers called with full name */
  1016. .get = ceph_get_xattr_handler,
  1017. .set = ceph_set_xattr_handler,
  1018. };
  1019. #ifdef CONFIG_SECURITY
  1020. bool ceph_security_xattr_wanted(struct inode *in)
  1021. {
  1022. return in->i_security != NULL;
  1023. }
  1024. bool ceph_security_xattr_deadlock(struct inode *in)
  1025. {
  1026. struct ceph_inode_info *ci;
  1027. bool ret;
  1028. if (!in->i_security)
  1029. return false;
  1030. ci = ceph_inode(in);
  1031. spin_lock(&ci->i_ceph_lock);
  1032. ret = !(ci->i_ceph_flags & CEPH_I_SEC_INITED) &&
  1033. !(ci->i_xattrs.version > 0 &&
  1034. __ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 0));
  1035. spin_unlock(&ci->i_ceph_lock);
  1036. return ret;
  1037. }
  1038. #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
  1039. int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
  1040. struct ceph_acl_sec_ctx *as_ctx)
  1041. {
  1042. struct ceph_pagelist *pagelist = as_ctx->pagelist;
  1043. const char *name;
  1044. size_t name_len;
  1045. int err;
  1046. err = security_dentry_init_security(dentry, mode, &dentry->d_name,
  1047. &as_ctx->sec_ctx,
  1048. &as_ctx->sec_ctxlen);
  1049. if (err < 0) {
  1050. WARN_ON_ONCE(err != -EOPNOTSUPP);
  1051. err = 0; /* do nothing */
  1052. goto out;
  1053. }
  1054. err = -ENOMEM;
  1055. if (!pagelist) {
  1056. pagelist = ceph_pagelist_alloc(GFP_KERNEL);
  1057. if (!pagelist)
  1058. goto out;
  1059. err = ceph_pagelist_reserve(pagelist, PAGE_SIZE);
  1060. if (err)
  1061. goto out;
  1062. ceph_pagelist_encode_32(pagelist, 1);
  1063. }
  1064. /*
  1065. * FIXME: Make security_dentry_init_security() generic. Currently
  1066. * It only supports single security module and only selinux has
  1067. * dentry_init_security hook.
  1068. */
  1069. name = XATTR_NAME_SELINUX;
  1070. name_len = strlen(name);
  1071. err = ceph_pagelist_reserve(pagelist,
  1072. 4 * 2 + name_len + as_ctx->sec_ctxlen);
  1073. if (err)
  1074. goto out;
  1075. if (as_ctx->pagelist) {
  1076. /* update count of KV pairs */
  1077. BUG_ON(pagelist->length <= sizeof(__le32));
  1078. if (list_is_singular(&pagelist->head)) {
  1079. le32_add_cpu((__le32*)pagelist->mapped_tail, 1);
  1080. } else {
  1081. struct page *page = list_first_entry(&pagelist->head,
  1082. struct page, lru);
  1083. void *addr = kmap_atomic(page);
  1084. le32_add_cpu((__le32*)addr, 1);
  1085. kunmap_atomic(addr);
  1086. }
  1087. } else {
  1088. as_ctx->pagelist = pagelist;
  1089. }
  1090. ceph_pagelist_encode_32(pagelist, name_len);
  1091. ceph_pagelist_append(pagelist, name, name_len);
  1092. ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen);
  1093. ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen);
  1094. err = 0;
  1095. out:
  1096. if (pagelist && !as_ctx->pagelist)
  1097. ceph_pagelist_release(pagelist);
  1098. return err;
  1099. }
  1100. #endif /* CONFIG_CEPH_FS_SECURITY_LABEL */
  1101. #endif /* CONFIG_SECURITY */
  1102. void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
  1103. {
  1104. #ifdef CONFIG_CEPH_FS_POSIX_ACL
  1105. posix_acl_release(as_ctx->acl);
  1106. posix_acl_release(as_ctx->default_acl);
  1107. #endif
  1108. #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
  1109. security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
  1110. #endif
  1111. if (as_ctx->pagelist)
  1112. ceph_pagelist_release(as_ctx->pagelist);
  1113. }
  1114. /*
  1115. * List of handlers for synthetic system.* attributes. Other
  1116. * attributes are handled directly.
  1117. */
  1118. const struct xattr_handler *ceph_xattr_handlers[] = {
  1119. #ifdef CONFIG_CEPH_FS_POSIX_ACL
  1120. &posix_acl_access_xattr_handler,
  1121. &posix_acl_default_xattr_handler,
  1122. #endif
  1123. &ceph_other_xattr_handler,
  1124. NULL,
  1125. };