xfs_attr.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. /*
  2. * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it would be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write the Free Software Foundation,
  16. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "xfs.h"
  19. #include "xfs_fs.h"
  20. #include "xfs_shared.h"
  21. #include "xfs_format.h"
  22. #include "xfs_log_format.h"
  23. #include "xfs_trans_resv.h"
  24. #include "xfs_bit.h"
  25. #include "xfs_mount.h"
  26. #include "xfs_da_format.h"
  27. #include "xfs_da_btree.h"
  28. #include "xfs_attr_sf.h"
  29. #include "xfs_inode.h"
  30. #include "xfs_alloc.h"
  31. #include "xfs_trans.h"
  32. #include "xfs_inode_item.h"
  33. #include "xfs_bmap.h"
  34. #include "xfs_bmap_util.h"
  35. #include "xfs_bmap_btree.h"
  36. #include "xfs_attr.h"
  37. #include "xfs_attr_leaf.h"
  38. #include "xfs_attr_remote.h"
  39. #include "xfs_error.h"
  40. #include "xfs_quota.h"
  41. #include "xfs_trans_space.h"
  42. #include "xfs_trace.h"
  43. /*
  44. * xfs_attr.c
  45. *
  46. * Provide the external interfaces to manage attribute lists.
  47. */
  48. /*========================================================================
  49. * Function prototypes for the kernel.
  50. *========================================================================*/
  51. /*
  52. * Internal routines when attribute list fits inside the inode.
  53. */
  54. STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
  55. /*
  56. * Internal routines when attribute list is one block.
  57. */
  58. STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
  59. STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
  60. STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
  61. /*
  62. * Internal routines when attribute list is more than one block.
  63. */
  64. STATIC int xfs_attr_node_get(xfs_da_args_t *args);
  65. STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
  66. STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
  67. STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
  68. STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
  69. STATIC int
  70. xfs_attr_args_init(
  71. struct xfs_da_args *args,
  72. struct xfs_inode *dp,
  73. const unsigned char *name,
  74. int flags)
  75. {
  76. if (!name)
  77. return -EINVAL;
  78. memset(args, 0, sizeof(*args));
  79. args->geo = dp->i_mount->m_attr_geo;
  80. args->whichfork = XFS_ATTR_FORK;
  81. args->dp = dp;
  82. args->flags = flags;
  83. args->name = name;
  84. args->namelen = strlen((const char *)name);
  85. if (args->namelen >= MAXNAMELEN)
  86. return -EFAULT; /* match IRIX behaviour */
  87. args->hashval = xfs_da_hashname(args->name, args->namelen);
  88. return 0;
  89. }
  90. int
  91. xfs_inode_hasattr(
  92. struct xfs_inode *ip)
  93. {
  94. if (!XFS_IFORK_Q(ip) ||
  95. (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
  96. ip->i_d.di_anextents == 0))
  97. return 0;
  98. return 1;
  99. }
  100. /*========================================================================
  101. * Overall external interface routines.
  102. *========================================================================*/
  103. int
  104. xfs_attr_get(
  105. struct xfs_inode *ip,
  106. const unsigned char *name,
  107. unsigned char *value,
  108. int *valuelenp,
  109. int flags)
  110. {
  111. struct xfs_da_args args;
  112. uint lock_mode;
  113. int error;
  114. XFS_STATS_INC(xs_attr_get);
  115. if (XFS_FORCED_SHUTDOWN(ip->i_mount))
  116. return -EIO;
  117. if (!xfs_inode_hasattr(ip))
  118. return -ENOATTR;
  119. error = xfs_attr_args_init(&args, ip, name, flags);
  120. if (error)
  121. return error;
  122. args.value = value;
  123. args.valuelen = *valuelenp;
  124. lock_mode = xfs_ilock_attr_map_shared(ip);
  125. if (!xfs_inode_hasattr(ip))
  126. error = -ENOATTR;
  127. else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
  128. error = xfs_attr_shortform_getvalue(&args);
  129. else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
  130. error = xfs_attr_leaf_get(&args);
  131. else
  132. error = xfs_attr_node_get(&args);
  133. xfs_iunlock(ip, lock_mode);
  134. *valuelenp = args.valuelen;
  135. return error == -EEXIST ? 0 : error;
  136. }
  137. /*
  138. * Calculate how many blocks we need for the new attribute,
  139. */
  140. STATIC int
  141. xfs_attr_calc_size(
  142. struct xfs_da_args *args,
  143. int *local)
  144. {
  145. struct xfs_mount *mp = args->dp->i_mount;
  146. int size;
  147. int nblks;
  148. /*
  149. * Determine space new attribute will use, and if it would be
  150. * "local" or "remote" (note: local != inline).
  151. */
  152. size = xfs_attr_leaf_newentsize(args, local);
  153. nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
  154. if (*local) {
  155. if (size > (args->geo->blksize / 2)) {
  156. /* Double split possible */
  157. nblks *= 2;
  158. }
  159. } else {
  160. /*
  161. * Out of line attribute, cannot double split, but
  162. * make room for the attribute value itself.
  163. */
  164. uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
  165. nblks += dblocks;
  166. nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
  167. }
  168. return nblks;
  169. }
  170. int
  171. xfs_attr_set(
  172. struct xfs_inode *dp,
  173. const unsigned char *name,
  174. unsigned char *value,
  175. int valuelen,
  176. int flags)
  177. {
  178. struct xfs_mount *mp = dp->i_mount;
  179. struct xfs_da_args args;
  180. struct xfs_bmap_free flist;
  181. struct xfs_trans_res tres;
  182. xfs_fsblock_t firstblock;
  183. int rsvd = (flags & ATTR_ROOT) != 0;
  184. int error, err2, committed, local;
  185. XFS_STATS_INC(xs_attr_set);
  186. if (XFS_FORCED_SHUTDOWN(dp->i_mount))
  187. return -EIO;
  188. error = xfs_attr_args_init(&args, dp, name, flags);
  189. if (error)
  190. return error;
  191. args.value = value;
  192. args.valuelen = valuelen;
  193. args.firstblock = &firstblock;
  194. args.flist = &flist;
  195. args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
  196. args.total = xfs_attr_calc_size(&args, &local);
  197. error = xfs_qm_dqattach(dp, 0);
  198. if (error)
  199. return error;
  200. /*
  201. * If the inode doesn't have an attribute fork, add one.
  202. * (inode must not be locked when we call this routine)
  203. */
  204. if (XFS_IFORK_Q(dp) == 0) {
  205. int sf_size = sizeof(xfs_attr_sf_hdr_t) +
  206. XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen);
  207. error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
  208. if (error)
  209. return error;
  210. }
  211. /*
  212. * Start our first transaction of the day.
  213. *
  214. * All future transactions during this code must be "chained" off
  215. * this one via the trans_dup() call. All transactions will contain
  216. * the inode, and the inode will always be marked with trans_ihold().
  217. * Since the inode will be locked in all transactions, we must log
  218. * the inode in every transaction to let it float upward through
  219. * the log.
  220. */
  221. args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);
  222. /*
  223. * Root fork attributes can use reserved data blocks for this
  224. * operation if necessary
  225. */
  226. if (rsvd)
  227. args.trans->t_flags |= XFS_TRANS_RESERVE;
  228. tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
  229. M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
  230. tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
  231. tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
  232. error = xfs_trans_reserve(args.trans, &tres, args.total, 0);
  233. if (error) {
  234. xfs_trans_cancel(args.trans);
  235. return error;
  236. }
  237. xfs_ilock(dp, XFS_ILOCK_EXCL);
  238. error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
  239. rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
  240. XFS_QMOPT_RES_REGBLKS);
  241. if (error) {
  242. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  243. xfs_trans_cancel(args.trans);
  244. return error;
  245. }
  246. xfs_trans_ijoin(args.trans, dp, 0);
  247. /*
  248. * If the attribute list is non-existent or a shortform list,
  249. * upgrade it to a single-leaf-block attribute list.
  250. */
  251. if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL ||
  252. (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
  253. dp->i_d.di_anextents == 0)) {
  254. /*
  255. * Build initial attribute list (if required).
  256. */
  257. if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
  258. xfs_attr_shortform_create(&args);
  259. /*
  260. * Try to add the attr to the attribute list in
  261. * the inode.
  262. */
  263. error = xfs_attr_shortform_addname(&args);
  264. if (error != -ENOSPC) {
  265. /*
  266. * Commit the shortform mods, and we're done.
  267. * NOTE: this is also the error path (EEXIST, etc).
  268. */
  269. ASSERT(args.trans != NULL);
  270. /*
  271. * If this is a synchronous mount, make sure that
  272. * the transaction goes to disk before returning
  273. * to the user.
  274. */
  275. if (mp->m_flags & XFS_MOUNT_WSYNC)
  276. xfs_trans_set_sync(args.trans);
  277. if (!error && (flags & ATTR_KERNOTIME) == 0) {
  278. xfs_trans_ichgtime(args.trans, dp,
  279. XFS_ICHGTIME_CHG);
  280. }
  281. err2 = xfs_trans_commit(args.trans);
  282. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  283. return error ? error : err2;
  284. }
  285. /*
  286. * It won't fit in the shortform, transform to a leaf block.
  287. * GROT: another possible req'mt for a double-split btree op.
  288. */
  289. xfs_bmap_init(args.flist, args.firstblock);
  290. error = xfs_attr_shortform_to_leaf(&args);
  291. if (!error) {
  292. error = xfs_bmap_finish(&args.trans, args.flist,
  293. &committed);
  294. }
  295. if (error) {
  296. ASSERT(committed);
  297. args.trans = NULL;
  298. xfs_bmap_cancel(&flist);
  299. goto out;
  300. }
  301. /*
  302. * bmap_finish() may have committed the last trans and started
  303. * a new one. We need the inode to be in all transactions.
  304. */
  305. if (committed)
  306. xfs_trans_ijoin(args.trans, dp, 0);
  307. /*
  308. * Commit the leaf transformation. We'll need another (linked)
  309. * transaction to add the new attribute to the leaf.
  310. */
  311. error = xfs_trans_roll(&args.trans, dp);
  312. if (error)
  313. goto out;
  314. }
  315. if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
  316. error = xfs_attr_leaf_addname(&args);
  317. else
  318. error = xfs_attr_node_addname(&args);
  319. if (error)
  320. goto out;
  321. /*
  322. * If this is a synchronous mount, make sure that the
  323. * transaction goes to disk before returning to the user.
  324. */
  325. if (mp->m_flags & XFS_MOUNT_WSYNC)
  326. xfs_trans_set_sync(args.trans);
  327. if ((flags & ATTR_KERNOTIME) == 0)
  328. xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
  329. /*
  330. * Commit the last in the sequence of transactions.
  331. */
  332. xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
  333. error = xfs_trans_commit(args.trans);
  334. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  335. return error;
  336. out:
  337. if (args.trans)
  338. xfs_trans_cancel(args.trans);
  339. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  340. return error;
  341. }
  342. /*
  343. * Generic handler routine to remove a name from an attribute list.
  344. * Transitions attribute list from Btree to shortform as necessary.
  345. */
  346. int
  347. xfs_attr_remove(
  348. struct xfs_inode *dp,
  349. const unsigned char *name,
  350. int flags)
  351. {
  352. struct xfs_mount *mp = dp->i_mount;
  353. struct xfs_da_args args;
  354. struct xfs_bmap_free flist;
  355. xfs_fsblock_t firstblock;
  356. int error;
  357. XFS_STATS_INC(xs_attr_remove);
  358. if (XFS_FORCED_SHUTDOWN(dp->i_mount))
  359. return -EIO;
  360. if (!xfs_inode_hasattr(dp))
  361. return -ENOATTR;
  362. error = xfs_attr_args_init(&args, dp, name, flags);
  363. if (error)
  364. return error;
  365. args.firstblock = &firstblock;
  366. args.flist = &flist;
  367. /*
  368. * we have no control over the attribute names that userspace passes us
  369. * to remove, so we have to allow the name lookup prior to attribute
  370. * removal to fail.
  371. */
  372. args.op_flags = XFS_DA_OP_OKNOENT;
  373. error = xfs_qm_dqattach(dp, 0);
  374. if (error)
  375. return error;
  376. /*
  377. * Start our first transaction of the day.
  378. *
  379. * All future transactions during this code must be "chained" off
  380. * this one via the trans_dup() call. All transactions will contain
  381. * the inode, and the inode will always be marked with trans_ihold().
  382. * Since the inode will be locked in all transactions, we must log
  383. * the inode in every transaction to let it float upward through
  384. * the log.
  385. */
  386. args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);
  387. /*
  388. * Root fork attributes can use reserved data blocks for this
  389. * operation if necessary
  390. */
  391. if (flags & ATTR_ROOT)
  392. args.trans->t_flags |= XFS_TRANS_RESERVE;
  393. error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm,
  394. XFS_ATTRRM_SPACE_RES(mp), 0);
  395. if (error) {
  396. xfs_trans_cancel(args.trans);
  397. return error;
  398. }
  399. xfs_ilock(dp, XFS_ILOCK_EXCL);
  400. /*
  401. * No need to make quota reservations here. We expect to release some
  402. * blocks not allocate in the common case.
  403. */
  404. xfs_trans_ijoin(args.trans, dp, 0);
  405. if (!xfs_inode_hasattr(dp)) {
  406. error = -ENOATTR;
  407. } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
  408. ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
  409. error = xfs_attr_shortform_remove(&args);
  410. } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
  411. error = xfs_attr_leaf_removename(&args);
  412. } else {
  413. error = xfs_attr_node_removename(&args);
  414. }
  415. if (error)
  416. goto out;
  417. /*
  418. * If this is a synchronous mount, make sure that the
  419. * transaction goes to disk before returning to the user.
  420. */
  421. if (mp->m_flags & XFS_MOUNT_WSYNC)
  422. xfs_trans_set_sync(args.trans);
  423. if ((flags & ATTR_KERNOTIME) == 0)
  424. xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
  425. /*
  426. * Commit the last in the sequence of transactions.
  427. */
  428. xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
  429. error = xfs_trans_commit(args.trans);
  430. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  431. return error;
  432. out:
  433. if (args.trans)
  434. xfs_trans_cancel(args.trans);
  435. xfs_iunlock(dp, XFS_ILOCK_EXCL);
  436. return error;
  437. }
  438. /*========================================================================
  439. * External routines when attribute list is inside the inode
  440. *========================================================================*/
  441. /*
  442. * Add a name to the shortform attribute list structure
  443. * This is the external routine.
  444. */
  445. STATIC int
  446. xfs_attr_shortform_addname(xfs_da_args_t *args)
  447. {
  448. int newsize, forkoff, retval;
  449. trace_xfs_attr_sf_addname(args);
  450. retval = xfs_attr_shortform_lookup(args);
  451. if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
  452. return retval;
  453. } else if (retval == -EEXIST) {
  454. if (args->flags & ATTR_CREATE)
  455. return retval;
  456. retval = xfs_attr_shortform_remove(args);
  457. ASSERT(retval == 0);
  458. }
  459. if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
  460. args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
  461. return -ENOSPC;
  462. newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
  463. newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
  464. forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
  465. if (!forkoff)
  466. return -ENOSPC;
  467. xfs_attr_shortform_add(args, forkoff);
  468. return 0;
  469. }
  470. /*========================================================================
  471. * External routines when attribute list is one block
  472. *========================================================================*/
  473. /*
  474. * Add a name to the leaf attribute list structure
  475. *
  476. * This leaf block cannot have a "remote" value, we only call this routine
  477. * if bmap_one_block() says there is only one block (ie: no remote blks).
  478. */
  479. STATIC int
  480. xfs_attr_leaf_addname(xfs_da_args_t *args)
  481. {
  482. xfs_inode_t *dp;
  483. struct xfs_buf *bp;
  484. int retval, error, committed, forkoff;
  485. trace_xfs_attr_leaf_addname(args);
  486. /*
  487. * Read the (only) block in the attribute list in.
  488. */
  489. dp = args->dp;
  490. args->blkno = 0;
  491. error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
  492. if (error)
  493. return error;
  494. /*
  495. * Look up the given attribute in the leaf block. Figure out if
  496. * the given flags produce an error or call for an atomic rename.
  497. */
  498. retval = xfs_attr3_leaf_lookup_int(bp, args);
  499. if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
  500. xfs_trans_brelse(args->trans, bp);
  501. return retval;
  502. } else if (retval == -EEXIST) {
  503. if (args->flags & ATTR_CREATE) { /* pure create op */
  504. xfs_trans_brelse(args->trans, bp);
  505. return retval;
  506. }
  507. trace_xfs_attr_leaf_replace(args);
  508. /* save the attribute state for later removal*/
  509. args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */
  510. args->blkno2 = args->blkno; /* set 2nd entry info*/
  511. args->index2 = args->index;
  512. args->rmtblkno2 = args->rmtblkno;
  513. args->rmtblkcnt2 = args->rmtblkcnt;
  514. args->rmtvaluelen2 = args->rmtvaluelen;
  515. /*
  516. * clear the remote attr state now that it is saved so that the
  517. * values reflect the state of the attribute we are about to
  518. * add, not the attribute we just found and will remove later.
  519. */
  520. args->rmtblkno = 0;
  521. args->rmtblkcnt = 0;
  522. args->rmtvaluelen = 0;
  523. }
  524. /*
  525. * Add the attribute to the leaf block, transitioning to a Btree
  526. * if required.
  527. */
  528. retval = xfs_attr3_leaf_add(bp, args);
  529. if (retval == -ENOSPC) {
  530. /*
  531. * Promote the attribute list to the Btree format, then
  532. * Commit that transaction so that the node_addname() call
  533. * can manage its own transactions.
  534. */
  535. xfs_bmap_init(args->flist, args->firstblock);
  536. error = xfs_attr3_leaf_to_node(args);
  537. if (!error) {
  538. error = xfs_bmap_finish(&args->trans, args->flist,
  539. &committed);
  540. }
  541. if (error) {
  542. ASSERT(committed);
  543. args->trans = NULL;
  544. xfs_bmap_cancel(args->flist);
  545. return error;
  546. }
  547. /*
  548. * bmap_finish() may have committed the last trans and started
  549. * a new one. We need the inode to be in all transactions.
  550. */
  551. if (committed)
  552. xfs_trans_ijoin(args->trans, dp, 0);
  553. /*
  554. * Commit the current trans (including the inode) and start
  555. * a new one.
  556. */
  557. error = xfs_trans_roll(&args->trans, dp);
  558. if (error)
  559. return error;
  560. /*
  561. * Fob the whole rest of the problem off on the Btree code.
  562. */
  563. error = xfs_attr_node_addname(args);
  564. return error;
  565. }
  566. /*
  567. * Commit the transaction that added the attr name so that
  568. * later routines can manage their own transactions.
  569. */
  570. error = xfs_trans_roll(&args->trans, dp);
  571. if (error)
  572. return error;
  573. /*
  574. * If there was an out-of-line value, allocate the blocks we
  575. * identified for its storage and copy the value. This is done
  576. * after we create the attribute so that we don't overflow the
  577. * maximum size of a transaction and/or hit a deadlock.
  578. */
  579. if (args->rmtblkno > 0) {
  580. error = xfs_attr_rmtval_set(args);
  581. if (error)
  582. return error;
  583. }
  584. /*
  585. * If this is an atomic rename operation, we must "flip" the
  586. * incomplete flags on the "new" and "old" attribute/value pairs
  587. * so that one disappears and one appears atomically. Then we
  588. * must remove the "old" attribute/value pair.
  589. */
  590. if (args->op_flags & XFS_DA_OP_RENAME) {
  591. /*
  592. * In a separate transaction, set the incomplete flag on the
  593. * "old" attr and clear the incomplete flag on the "new" attr.
  594. */
  595. error = xfs_attr3_leaf_flipflags(args);
  596. if (error)
  597. return error;
  598. /*
  599. * Dismantle the "old" attribute/value pair by removing
  600. * a "remote" value (if it exists).
  601. */
  602. args->index = args->index2;
  603. args->blkno = args->blkno2;
  604. args->rmtblkno = args->rmtblkno2;
  605. args->rmtblkcnt = args->rmtblkcnt2;
  606. args->rmtvaluelen = args->rmtvaluelen2;
  607. if (args->rmtblkno) {
  608. error = xfs_attr_rmtval_remove(args);
  609. if (error)
  610. return error;
  611. }
  612. /*
  613. * Read in the block containing the "old" attr, then
  614. * remove the "old" attr from that block (neat, huh!)
  615. */
  616. error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
  617. -1, &bp);
  618. if (error)
  619. return error;
  620. xfs_attr3_leaf_remove(bp, args);
  621. /*
  622. * If the result is small enough, shrink it all into the inode.
  623. */
  624. if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
  625. xfs_bmap_init(args->flist, args->firstblock);
  626. error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
  627. /* bp is gone due to xfs_da_shrink_inode */
  628. if (!error) {
  629. error = xfs_bmap_finish(&args->trans,
  630. args->flist,
  631. &committed);
  632. }
  633. if (error) {
  634. ASSERT(committed);
  635. args->trans = NULL;
  636. xfs_bmap_cancel(args->flist);
  637. return error;
  638. }
  639. /*
  640. * bmap_finish() may have committed the last trans
  641. * and started a new one. We need the inode to be
  642. * in all transactions.
  643. */
  644. if (committed)
  645. xfs_trans_ijoin(args->trans, dp, 0);
  646. }
  647. /*
  648. * Commit the remove and start the next trans in series.
  649. */
  650. error = xfs_trans_roll(&args->trans, dp);
  651. } else if (args->rmtblkno > 0) {
  652. /*
  653. * Added a "remote" value, just clear the incomplete flag.
  654. */
  655. error = xfs_attr3_leaf_clearflag(args);
  656. }
  657. return error;
  658. }
  659. /*
  660. * Remove a name from the leaf attribute list structure
  661. *
  662. * This leaf block cannot have a "remote" value, we only call this routine
  663. * if bmap_one_block() says there is only one block (ie: no remote blks).
  664. */
  665. STATIC int
  666. xfs_attr_leaf_removename(xfs_da_args_t *args)
  667. {
  668. xfs_inode_t *dp;
  669. struct xfs_buf *bp;
  670. int error, committed, forkoff;
  671. trace_xfs_attr_leaf_removename(args);
  672. /*
  673. * Remove the attribute.
  674. */
  675. dp = args->dp;
  676. args->blkno = 0;
  677. error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
  678. if (error)
  679. return error;
  680. error = xfs_attr3_leaf_lookup_int(bp, args);
  681. if (error == -ENOATTR) {
  682. xfs_trans_brelse(args->trans, bp);
  683. return error;
  684. }
  685. xfs_attr3_leaf_remove(bp, args);
  686. /*
  687. * If the result is small enough, shrink it all into the inode.
  688. */
  689. if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
  690. xfs_bmap_init(args->flist, args->firstblock);
  691. error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
  692. /* bp is gone due to xfs_da_shrink_inode */
  693. if (!error) {
  694. error = xfs_bmap_finish(&args->trans, args->flist,
  695. &committed);
  696. }
  697. if (error) {
  698. ASSERT(committed);
  699. args->trans = NULL;
  700. xfs_bmap_cancel(args->flist);
  701. return error;
  702. }
  703. /*
  704. * bmap_finish() may have committed the last trans and started
  705. * a new one. We need the inode to be in all transactions.
  706. */
  707. if (committed)
  708. xfs_trans_ijoin(args->trans, dp, 0);
  709. }
  710. return 0;
  711. }
  712. /*
  713. * Look up a name in a leaf attribute list structure.
  714. *
  715. * This leaf block cannot have a "remote" value, we only call this routine
  716. * if bmap_one_block() says there is only one block (ie: no remote blks).
  717. */
  718. STATIC int
  719. xfs_attr_leaf_get(xfs_da_args_t *args)
  720. {
  721. struct xfs_buf *bp;
  722. int error;
  723. trace_xfs_attr_leaf_get(args);
  724. args->blkno = 0;
  725. error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
  726. if (error)
  727. return error;
  728. error = xfs_attr3_leaf_lookup_int(bp, args);
  729. if (error != -EEXIST) {
  730. xfs_trans_brelse(args->trans, bp);
  731. return error;
  732. }
  733. error = xfs_attr3_leaf_getvalue(bp, args);
  734. xfs_trans_brelse(args->trans, bp);
  735. if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
  736. error = xfs_attr_rmtval_get(args);
  737. }
  738. return error;
  739. }
  740. /*========================================================================
  741. * External routines when attribute list size > geo->blksize
  742. *========================================================================*/
  743. /*
  744. * Add a name to a Btree-format attribute list.
  745. *
  746. * This will involve walking down the Btree, and may involve splitting
  747. * leaf nodes and even splitting intermediate nodes up to and including
  748. * the root node (a special case of an intermediate node).
  749. *
  750. * "Remote" attribute values confuse the issue and atomic rename operations
  751. * add a whole extra layer of confusion on top of that.
  752. */
  753. STATIC int
  754. xfs_attr_node_addname(xfs_da_args_t *args)
  755. {
  756. xfs_da_state_t *state;
  757. xfs_da_state_blk_t *blk;
  758. xfs_inode_t *dp;
  759. xfs_mount_t *mp;
  760. int committed, retval, error;
  761. trace_xfs_attr_node_addname(args);
  762. /*
  763. * Fill in bucket of arguments/results/context to carry around.
  764. */
  765. dp = args->dp;
  766. mp = dp->i_mount;
  767. restart:
  768. state = xfs_da_state_alloc();
  769. state->args = args;
  770. state->mp = mp;
  771. /*
  772. * Search to see if name already exists, and get back a pointer
  773. * to where it should go.
  774. */
  775. error = xfs_da3_node_lookup_int(state, &retval);
  776. if (error)
  777. goto out;
  778. blk = &state->path.blk[ state->path.active-1 ];
  779. ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
  780. if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
  781. goto out;
  782. } else if (retval == -EEXIST) {
  783. if (args->flags & ATTR_CREATE)
  784. goto out;
  785. trace_xfs_attr_node_replace(args);
  786. /* save the attribute state for later removal*/
  787. args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */
  788. args->blkno2 = args->blkno; /* set 2nd entry info*/
  789. args->index2 = args->index;
  790. args->rmtblkno2 = args->rmtblkno;
  791. args->rmtblkcnt2 = args->rmtblkcnt;
  792. args->rmtvaluelen2 = args->rmtvaluelen;
  793. /*
  794. * clear the remote attr state now that it is saved so that the
  795. * values reflect the state of the attribute we are about to
  796. * add, not the attribute we just found and will remove later.
  797. */
  798. args->rmtblkno = 0;
  799. args->rmtblkcnt = 0;
  800. args->rmtvaluelen = 0;
  801. }
  802. retval = xfs_attr3_leaf_add(blk->bp, state->args);
  803. if (retval == -ENOSPC) {
  804. if (state->path.active == 1) {
  805. /*
  806. * Its really a single leaf node, but it had
  807. * out-of-line values so it looked like it *might*
  808. * have been a b-tree.
  809. */
  810. xfs_da_state_free(state);
  811. state = NULL;
  812. xfs_bmap_init(args->flist, args->firstblock);
  813. error = xfs_attr3_leaf_to_node(args);
  814. if (!error) {
  815. error = xfs_bmap_finish(&args->trans,
  816. args->flist,
  817. &committed);
  818. }
  819. if (error) {
  820. ASSERT(committed);
  821. args->trans = NULL;
  822. xfs_bmap_cancel(args->flist);
  823. goto out;
  824. }
  825. /*
  826. * bmap_finish() may have committed the last trans
  827. * and started a new one. We need the inode to be
  828. * in all transactions.
  829. */
  830. if (committed)
  831. xfs_trans_ijoin(args->trans, dp, 0);
  832. /*
  833. * Commit the node conversion and start the next
  834. * trans in the chain.
  835. */
  836. error = xfs_trans_roll(&args->trans, dp);
  837. if (error)
  838. goto out;
  839. goto restart;
  840. }
  841. /*
  842. * Split as many Btree elements as required.
  843. * This code tracks the new and old attr's location
  844. * in the index/blkno/rmtblkno/rmtblkcnt fields and
  845. * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
  846. */
  847. xfs_bmap_init(args->flist, args->firstblock);
  848. error = xfs_da3_split(state);
  849. if (!error) {
  850. error = xfs_bmap_finish(&args->trans, args->flist,
  851. &committed);
  852. }
  853. if (error) {
  854. ASSERT(committed);
  855. args->trans = NULL;
  856. xfs_bmap_cancel(args->flist);
  857. goto out;
  858. }
  859. /*
  860. * bmap_finish() may have committed the last trans and started
  861. * a new one. We need the inode to be in all transactions.
  862. */
  863. if (committed)
  864. xfs_trans_ijoin(args->trans, dp, 0);
  865. } else {
  866. /*
  867. * Addition succeeded, update Btree hashvals.
  868. */
  869. xfs_da3_fixhashpath(state, &state->path);
  870. }
  871. /*
  872. * Kill the state structure, we're done with it and need to
  873. * allow the buffers to come back later.
  874. */
  875. xfs_da_state_free(state);
  876. state = NULL;
  877. /*
  878. * Commit the leaf addition or btree split and start the next
  879. * trans in the chain.
  880. */
  881. error = xfs_trans_roll(&args->trans, dp);
  882. if (error)
  883. goto out;
  884. /*
  885. * If there was an out-of-line value, allocate the blocks we
  886. * identified for its storage and copy the value. This is done
  887. * after we create the attribute so that we don't overflow the
  888. * maximum size of a transaction and/or hit a deadlock.
  889. */
  890. if (args->rmtblkno > 0) {
  891. error = xfs_attr_rmtval_set(args);
  892. if (error)
  893. return error;
  894. }
  895. /*
  896. * If this is an atomic rename operation, we must "flip" the
  897. * incomplete flags on the "new" and "old" attribute/value pairs
  898. * so that one disappears and one appears atomically. Then we
  899. * must remove the "old" attribute/value pair.
  900. */
  901. if (args->op_flags & XFS_DA_OP_RENAME) {
  902. /*
  903. * In a separate transaction, set the incomplete flag on the
  904. * "old" attr and clear the incomplete flag on the "new" attr.
  905. */
  906. error = xfs_attr3_leaf_flipflags(args);
  907. if (error)
  908. goto out;
  909. /*
  910. * Dismantle the "old" attribute/value pair by removing
  911. * a "remote" value (if it exists).
  912. */
  913. args->index = args->index2;
  914. args->blkno = args->blkno2;
  915. args->rmtblkno = args->rmtblkno2;
  916. args->rmtblkcnt = args->rmtblkcnt2;
  917. args->rmtvaluelen = args->rmtvaluelen2;
  918. if (args->rmtblkno) {
  919. error = xfs_attr_rmtval_remove(args);
  920. if (error)
  921. return error;
  922. }
  923. /*
  924. * Re-find the "old" attribute entry after any split ops.
  925. * The INCOMPLETE flag means that we will find the "old"
  926. * attr, not the "new" one.
  927. */
  928. args->flags |= XFS_ATTR_INCOMPLETE;
  929. state = xfs_da_state_alloc();
  930. state->args = args;
  931. state->mp = mp;
  932. state->inleaf = 0;
  933. error = xfs_da3_node_lookup_int(state, &retval);
  934. if (error)
  935. goto out;
  936. /*
  937. * Remove the name and update the hashvals in the tree.
  938. */
  939. blk = &state->path.blk[ state->path.active-1 ];
  940. ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
  941. error = xfs_attr3_leaf_remove(blk->bp, args);
  942. xfs_da3_fixhashpath(state, &state->path);
  943. /*
  944. * Check to see if the tree needs to be collapsed.
  945. */
  946. if (retval && (state->path.active > 1)) {
  947. xfs_bmap_init(args->flist, args->firstblock);
  948. error = xfs_da3_join(state);
  949. if (!error) {
  950. error = xfs_bmap_finish(&args->trans,
  951. args->flist,
  952. &committed);
  953. }
  954. if (error) {
  955. ASSERT(committed);
  956. args->trans = NULL;
  957. xfs_bmap_cancel(args->flist);
  958. goto out;
  959. }
  960. /*
  961. * bmap_finish() may have committed the last trans
  962. * and started a new one. We need the inode to be
  963. * in all transactions.
  964. */
  965. if (committed)
  966. xfs_trans_ijoin(args->trans, dp, 0);
  967. }
  968. /*
  969. * Commit and start the next trans in the chain.
  970. */
  971. error = xfs_trans_roll(&args->trans, dp);
  972. if (error)
  973. goto out;
  974. } else if (args->rmtblkno > 0) {
  975. /*
  976. * Added a "remote" value, just clear the incomplete flag.
  977. */
  978. error = xfs_attr3_leaf_clearflag(args);
  979. if (error)
  980. goto out;
  981. }
  982. retval = error = 0;
  983. out:
  984. if (state)
  985. xfs_da_state_free(state);
  986. if (error)
  987. return error;
  988. return retval;
  989. }
  990. /*
  991. * Remove a name from a B-tree attribute list.
  992. *
  993. * This will involve walking down the Btree, and may involve joining
  994. * leaf nodes and even joining intermediate nodes up to and including
  995. * the root node (a special case of an intermediate node).
  996. */
  997. STATIC int
  998. xfs_attr_node_removename(xfs_da_args_t *args)
  999. {
  1000. xfs_da_state_t *state;
  1001. xfs_da_state_blk_t *blk;
  1002. xfs_inode_t *dp;
  1003. struct xfs_buf *bp;
  1004. int retval, error, committed, forkoff;
  1005. trace_xfs_attr_node_removename(args);
  1006. /*
  1007. * Tie a string around our finger to remind us where we are.
  1008. */
  1009. dp = args->dp;
  1010. state = xfs_da_state_alloc();
  1011. state->args = args;
  1012. state->mp = dp->i_mount;
  1013. /*
  1014. * Search to see if name exists, and get back a pointer to it.
  1015. */
  1016. error = xfs_da3_node_lookup_int(state, &retval);
  1017. if (error || (retval != -EEXIST)) {
  1018. if (error == 0)
  1019. error = retval;
  1020. goto out;
  1021. }
  1022. /*
  1023. * If there is an out-of-line value, de-allocate the blocks.
  1024. * This is done before we remove the attribute so that we don't
  1025. * overflow the maximum size of a transaction and/or hit a deadlock.
  1026. */
  1027. blk = &state->path.blk[ state->path.active-1 ];
  1028. ASSERT(blk->bp != NULL);
  1029. ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
  1030. if (args->rmtblkno > 0) {
  1031. /*
  1032. * Fill in disk block numbers in the state structure
  1033. * so that we can get the buffers back after we commit
  1034. * several transactions in the following calls.
  1035. */
  1036. error = xfs_attr_fillstate(state);
  1037. if (error)
  1038. goto out;
  1039. /*
  1040. * Mark the attribute as INCOMPLETE, then bunmapi() the
  1041. * remote value.
  1042. */
  1043. error = xfs_attr3_leaf_setflag(args);
  1044. if (error)
  1045. goto out;
  1046. error = xfs_attr_rmtval_remove(args);
  1047. if (error)
  1048. goto out;
  1049. /*
  1050. * Refill the state structure with buffers, the prior calls
  1051. * released our buffers.
  1052. */
  1053. error = xfs_attr_refillstate(state);
  1054. if (error)
  1055. goto out;
  1056. }
  1057. /*
  1058. * Remove the name and update the hashvals in the tree.
  1059. */
  1060. blk = &state->path.blk[ state->path.active-1 ];
  1061. ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
  1062. retval = xfs_attr3_leaf_remove(blk->bp, args);
  1063. xfs_da3_fixhashpath(state, &state->path);
  1064. /*
  1065. * Check to see if the tree needs to be collapsed.
  1066. */
  1067. if (retval && (state->path.active > 1)) {
  1068. xfs_bmap_init(args->flist, args->firstblock);
  1069. error = xfs_da3_join(state);
  1070. if (!error) {
  1071. error = xfs_bmap_finish(&args->trans, args->flist,
  1072. &committed);
  1073. }
  1074. if (error) {
  1075. ASSERT(committed);
  1076. args->trans = NULL;
  1077. xfs_bmap_cancel(args->flist);
  1078. goto out;
  1079. }
  1080. /*
  1081. * bmap_finish() may have committed the last trans and started
  1082. * a new one. We need the inode to be in all transactions.
  1083. */
  1084. if (committed)
  1085. xfs_trans_ijoin(args->trans, dp, 0);
  1086. /*
  1087. * Commit the Btree join operation and start a new trans.
  1088. */
  1089. error = xfs_trans_roll(&args->trans, dp);
  1090. if (error)
  1091. goto out;
  1092. }
  1093. /*
  1094. * If the result is small enough, push it all into the inode.
  1095. */
  1096. if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
  1097. /*
  1098. * Have to get rid of the copy of this dabuf in the state.
  1099. */
  1100. ASSERT(state->path.active == 1);
  1101. ASSERT(state->path.blk[0].bp);
  1102. state->path.blk[0].bp = NULL;
  1103. error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp);
  1104. if (error)
  1105. goto out;
  1106. if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
  1107. xfs_bmap_init(args->flist, args->firstblock);
  1108. error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
  1109. /* bp is gone due to xfs_da_shrink_inode */
  1110. if (!error) {
  1111. error = xfs_bmap_finish(&args->trans,
  1112. args->flist,
  1113. &committed);
  1114. }
  1115. if (error) {
  1116. ASSERT(committed);
  1117. args->trans = NULL;
  1118. xfs_bmap_cancel(args->flist);
  1119. goto out;
  1120. }
  1121. /*
  1122. * bmap_finish() may have committed the last trans
  1123. * and started a new one. We need the inode to be
  1124. * in all transactions.
  1125. */
  1126. if (committed)
  1127. xfs_trans_ijoin(args->trans, dp, 0);
  1128. } else
  1129. xfs_trans_brelse(args->trans, bp);
  1130. }
  1131. error = 0;
  1132. out:
  1133. xfs_da_state_free(state);
  1134. return error;
  1135. }
  1136. /*
  1137. * Fill in the disk block numbers in the state structure for the buffers
  1138. * that are attached to the state structure.
  1139. * This is done so that we can quickly reattach ourselves to those buffers
  1140. * after some set of transaction commits have released these buffers.
  1141. */
  1142. STATIC int
  1143. xfs_attr_fillstate(xfs_da_state_t *state)
  1144. {
  1145. xfs_da_state_path_t *path;
  1146. xfs_da_state_blk_t *blk;
  1147. int level;
  1148. trace_xfs_attr_fillstate(state->args);
  1149. /*
  1150. * Roll down the "path" in the state structure, storing the on-disk
  1151. * block number for those buffers in the "path".
  1152. */
  1153. path = &state->path;
  1154. ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
  1155. for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
  1156. if (blk->bp) {
  1157. blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
  1158. blk->bp = NULL;
  1159. } else {
  1160. blk->disk_blkno = 0;
  1161. }
  1162. }
  1163. /*
  1164. * Roll down the "altpath" in the state structure, storing the on-disk
  1165. * block number for those buffers in the "altpath".
  1166. */
  1167. path = &state->altpath;
  1168. ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
  1169. for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
  1170. if (blk->bp) {
  1171. blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
  1172. blk->bp = NULL;
  1173. } else {
  1174. blk->disk_blkno = 0;
  1175. }
  1176. }
  1177. return 0;
  1178. }
  1179. /*
  1180. * Reattach the buffers to the state structure based on the disk block
  1181. * numbers stored in the state structure.
  1182. * This is done after some set of transaction commits have released those
  1183. * buffers from our grip.
  1184. */
  1185. STATIC int
  1186. xfs_attr_refillstate(xfs_da_state_t *state)
  1187. {
  1188. xfs_da_state_path_t *path;
  1189. xfs_da_state_blk_t *blk;
  1190. int level, error;
  1191. trace_xfs_attr_refillstate(state->args);
  1192. /*
  1193. * Roll down the "path" in the state structure, storing the on-disk
  1194. * block number for those buffers in the "path".
  1195. */
  1196. path = &state->path;
  1197. ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
  1198. for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
  1199. if (blk->disk_blkno) {
  1200. error = xfs_da3_node_read(state->args->trans,
  1201. state->args->dp,
  1202. blk->blkno, blk->disk_blkno,
  1203. &blk->bp, XFS_ATTR_FORK);
  1204. if (error)
  1205. return error;
  1206. } else {
  1207. blk->bp = NULL;
  1208. }
  1209. }
  1210. /*
  1211. * Roll down the "altpath" in the state structure, storing the on-disk
  1212. * block number for those buffers in the "altpath".
  1213. */
  1214. path = &state->altpath;
  1215. ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
  1216. for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
  1217. if (blk->disk_blkno) {
  1218. error = xfs_da3_node_read(state->args->trans,
  1219. state->args->dp,
  1220. blk->blkno, blk->disk_blkno,
  1221. &blk->bp, XFS_ATTR_FORK);
  1222. if (error)
  1223. return error;
  1224. } else {
  1225. blk->bp = NULL;
  1226. }
  1227. }
  1228. return 0;
  1229. }
  1230. /*
  1231. * Look up a filename in a node attribute list.
  1232. *
  1233. * This routine gets called for any attribute fork that has more than one
  1234. * block, ie: both true Btree attr lists and for single-leaf-blocks with
  1235. * "remote" values taking up more blocks.
  1236. */
  1237. STATIC int
  1238. xfs_attr_node_get(xfs_da_args_t *args)
  1239. {
  1240. xfs_da_state_t *state;
  1241. xfs_da_state_blk_t *blk;
  1242. int error, retval;
  1243. int i;
  1244. trace_xfs_attr_node_get(args);
  1245. state = xfs_da_state_alloc();
  1246. state->args = args;
  1247. state->mp = args->dp->i_mount;
  1248. /*
  1249. * Search to see if name exists, and get back a pointer to it.
  1250. */
  1251. error = xfs_da3_node_lookup_int(state, &retval);
  1252. if (error) {
  1253. retval = error;
  1254. } else if (retval == -EEXIST) {
  1255. blk = &state->path.blk[ state->path.active-1 ];
  1256. ASSERT(blk->bp != NULL);
  1257. ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
  1258. /*
  1259. * Get the value, local or "remote"
  1260. */
  1261. retval = xfs_attr3_leaf_getvalue(blk->bp, args);
  1262. if (!retval && (args->rmtblkno > 0)
  1263. && !(args->flags & ATTR_KERNOVAL)) {
  1264. retval = xfs_attr_rmtval_get(args);
  1265. }
  1266. }
  1267. /*
  1268. * If not in a transaction, we have to release all the buffers.
  1269. */
  1270. for (i = 0; i < state->path.active; i++) {
  1271. xfs_trans_brelse(args->trans, state->path.blk[i].bp);
  1272. state->path.blk[i].bp = NULL;
  1273. }
  1274. xfs_da_state_free(state);
  1275. return retval;
  1276. }