1/* 2 * Copyright (c) 2000-2003 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_bit.h" 21#include "xfs_log.h" 22#include "xfs_inum.h" 23#include "xfs_trans.h" 24#include "xfs_sb.h" 25#include "xfs_ag.h" 26#include "xfs_dir2.h" 27#include "xfs_alloc.h" 28#include "xfs_dmapi.h" 29#include "xfs_quota.h" 30#include "xfs_mount.h" 31#include "xfs_bmap_btree.h" 32#include "xfs_alloc_btree.h" 33#include "xfs_ialloc_btree.h" 34#include "xfs_dir2_sf.h" 35#include "xfs_attr_sf.h" 36#include "xfs_dinode.h" 37#include "xfs_inode.h" 38#include "xfs_bmap.h" 39#include "xfs_btree.h" 40#include "xfs_ialloc.h" 41#include "xfs_rtalloc.h" 42#include "xfs_error.h" 43#include "xfs_itable.h" 44#include "xfs_rw.h" 45#include "xfs_acl.h" 46#include "xfs_attr.h" 47#include "xfs_buf_item.h" 48#include "xfs_trans_priv.h" 49#include "xfs_qm.h" 50 51/* 52 * returns the number of iovecs needed to log the given dquot item. 53 */ 54/* ARGSUSED */ 55STATIC uint 56xfs_qm_dquot_logitem_size( 57 xfs_dq_logitem_t *logitem) 58{ 59 /* 60 * we need only two iovecs, one for the format, one for the real thing 61 */ 62 return (2); 63} 64 65/* 66 * fills in the vector of log iovecs for the given dquot log item. 67 */ 68STATIC void 69xfs_qm_dquot_logitem_format( 70 xfs_dq_logitem_t *logitem, 71 xfs_log_iovec_t *logvec) 72{ 73 ASSERT(logitem); 74 ASSERT(logitem->qli_dquot); 75 76 logvec->i_addr = (xfs_caddr_t)&logitem->qli_format; 77 logvec->i_len = sizeof(xfs_dq_logformat_t); 78 XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_QFORMAT); 79 logvec++; 80 logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core; 81 logvec->i_len = sizeof(xfs_disk_dquot_t); 82 XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_DQUOT); 83 84 ASSERT(2 == logitem->qli_item.li_desc->lid_size); 85 logitem->qli_format.qlf_size = 2; 86 87} 88 89/* 90 * Increment the pin count of the given dquot. 91 * This value is protected by pinlock spinlock in the xQM structure. 92 */ 93STATIC void 94xfs_qm_dquot_logitem_pin( 95 xfs_dq_logitem_t *logitem) 96{ 97 unsigned long s; 98 xfs_dquot_t *dqp; 99 100 dqp = logitem->qli_dquot; 101 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 102 s = XFS_DQ_PINLOCK(dqp); 103 dqp->q_pincount++; 104 XFS_DQ_PINUNLOCK(dqp, s); 105} 106 107/* 108 * Decrement the pin count of the given dquot, and wake up 109 * anyone in xfs_dqwait_unpin() if the count goes to 0. The 110 * dquot must have been previously pinned with a call to xfs_dqpin(). 111 */ 112/* ARGSUSED */ 113STATIC void 114xfs_qm_dquot_logitem_unpin( 115 xfs_dq_logitem_t *logitem, 116 int stale) 117{ 118 unsigned long s; 119 xfs_dquot_t *dqp; 120 121 dqp = logitem->qli_dquot; 122 ASSERT(dqp->q_pincount > 0); 123 s = XFS_DQ_PINLOCK(dqp); 124 dqp->q_pincount--; 125 if (dqp->q_pincount == 0) { 126 sv_broadcast(&dqp->q_pinwait); 127 } 128 XFS_DQ_PINUNLOCK(dqp, s); 129} 130 131/* ARGSUSED */ 132STATIC void 133xfs_qm_dquot_logitem_unpin_remove( 134 xfs_dq_logitem_t *logitem, 135 xfs_trans_t *tp) 136{ 137 xfs_qm_dquot_logitem_unpin(logitem, 0); 138} 139 140/* 141 * Given the logitem, this writes the corresponding dquot entry to disk 142 * asynchronously. This is called with the dquot entry securely locked; 143 * we simply get xfs_qm_dqflush() to do the work, and unlock the dquot 144 * at the end. 145 */ 146STATIC void 147xfs_qm_dquot_logitem_push( 148 xfs_dq_logitem_t *logitem) 149{ 150 xfs_dquot_t *dqp; 151 152 dqp = logitem->qli_dquot; 153 154 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 155 ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp)); 156 157 /* 158 * Since we were able to lock the dquot's flush lock and 159 * we found it on the AIL, the dquot must be dirty. This 160 * is because the dquot is removed from the AIL while still 161 * holding the flush lock in xfs_dqflush_done(). Thus, if 162 * we found it in the AIL and were able to obtain the flush 163 * lock without sleeping, then there must not have been 164 * anyone in the process of flushing the dquot. 165 */ 166 xfs_qm_dqflush(dqp, XFS_B_DELWRI); 167 xfs_dqunlock(dqp); 168} 169 170/*ARGSUSED*/ 171STATIC xfs_lsn_t 172xfs_qm_dquot_logitem_committed( 173 xfs_dq_logitem_t *l, 174 xfs_lsn_t lsn) 175{ 176 /* 177 * We always re-log the entire dquot when it becomes dirty, 178 * so, the latest copy _is_ the only one that matters. 179 */ 180 return (lsn); 181} 182 183 184/* 185 * This is called to wait for the given dquot to be unpinned. 186 * Most of these pin/unpin routines are plagiarized from inode code. 187 */ 188void 189xfs_qm_dqunpin_wait( 190 xfs_dquot_t *dqp) 191{ 192 SPLDECL(s); 193 194 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 195 if (dqp->q_pincount == 0) { 196 return; 197 } 198 199 /* 200 * Give the log a push so we don't wait here too long. 201 */ 202 xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); 203 s = XFS_DQ_PINLOCK(dqp); 204 if (dqp->q_pincount == 0) { 205 XFS_DQ_PINUNLOCK(dqp, s); 206 return; 207 } 208 sv_wait(&(dqp->q_pinwait), PINOD, 209 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s); 210} 211 212/* 213 * This is called when IOP_TRYLOCK returns XFS_ITEM_PUSHBUF to indicate that 214 * the dquot is locked by us, but the flush lock isn't. So, here we are 215 * going to see if the relevant dquot buffer is incore, waiting on DELWRI. 216 * If so, we want to push it out to help us take this item off the AIL as soon 217 * as possible. 218 * 219 * We must not be holding the AIL_LOCK at this point. Calling incore() to 220 * search the buffer cache can be a time consuming thing, and AIL_LOCK is a 221 * spinlock. 222 */ 223STATIC void 224xfs_qm_dquot_logitem_pushbuf( 225 xfs_dq_logitem_t *qip) 226{ 227 xfs_dquot_t *dqp; 228 xfs_mount_t *mp; 229 xfs_buf_t *bp; 230 uint dopush; 231 232 dqp = qip->qli_dquot; 233 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 234 235 /* 236 * The qli_pushbuf_flag keeps others from 237 * trying to duplicate our effort. 238 */ 239 ASSERT(qip->qli_pushbuf_flag != 0); 240 ASSERT(qip->qli_push_owner == current_pid()); 241 242 /* 243 * If flushlock isn't locked anymore, chances are that the 244 * inode flush completed and the inode was taken off the AIL. 245 * So, just get out. 246 */ 247 if (!issemalocked(&(dqp->q_flock)) || 248 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { 249 qip->qli_pushbuf_flag = 0; 250 xfs_dqunlock(dqp); 251 return; 252 } 253 mp = dqp->q_mount; 254 bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno, 255 XFS_QI_DQCHUNKLEN(mp), 256 XFS_INCORE_TRYLOCK); 257 if (bp != NULL) { 258 if (XFS_BUF_ISDELAYWRITE(bp)) { 259 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && 260 issemalocked(&(dqp->q_flock))); 261 qip->qli_pushbuf_flag = 0; 262 xfs_dqunlock(dqp); 263 264 if (XFS_BUF_ISPINNED(bp)) { 265 xfs_log_force(mp, (xfs_lsn_t)0, 266 XFS_LOG_FORCE); 267 } 268 if (dopush) { 269#ifdef XFSRACEDEBUG 270 delay_for_intr(); 271 delay(300); 272#endif 273 xfs_bawrite(mp, bp); 274 } else { 275 xfs_buf_relse(bp); 276 } 277 } else { 278 qip->qli_pushbuf_flag = 0; 279 xfs_dqunlock(dqp); 280 xfs_buf_relse(bp); 281 } 282 return; 283 } 284 285 qip->qli_pushbuf_flag = 0; 286 xfs_dqunlock(dqp); 287} 288 289/* 290 * This is called to attempt to lock the dquot associated with this 291 * dquot log item. Don't sleep on the dquot lock or the flush lock. 292 * If the flush lock is already held, indicating that the dquot has 293 * been or is in the process of being flushed, then see if we can 294 * find the dquot's buffer in the buffer cache without sleeping. If 295 * we can and it is marked delayed write, then we want to send it out. 296 * We delay doing so until the push routine, though, to avoid sleeping 297 * in any device strategy routines. 298 */ 299STATIC uint 300xfs_qm_dquot_logitem_trylock( 301 xfs_dq_logitem_t *qip) 302{ 303 xfs_dquot_t *dqp; 304 uint retval; 305 306 dqp = qip->qli_dquot; 307 if (dqp->q_pincount > 0) 308 return (XFS_ITEM_PINNED); 309 310 if (! xfs_qm_dqlock_nowait(dqp)) 311 return (XFS_ITEM_LOCKED); 312 313 retval = XFS_ITEM_SUCCESS; 314 if (! xfs_qm_dqflock_nowait(dqp)) { 315 /* 316 * The dquot is already being flushed. It may have been 317 * flushed delayed write, however, and we don't want to 318 * get stuck waiting for that to complete. So, we want to check 319 * to see if we can lock the dquot's buffer without sleeping. 320 * If we can and it is marked for delayed write, then we 321 * hold it and send it out from the push routine. We don't 322 * want to do that now since we might sleep in the device 323 * strategy routine. We also don't want to grab the buffer lock 324 * here because we'd like not to call into the buffer cache 325 * while holding the AIL_LOCK. 326 * Make sure to only return PUSHBUF if we set pushbuf_flag 327 * ourselves. If someone else is doing it then we don't 328 * want to go to the push routine and duplicate their efforts. 329 */ 330 if (qip->qli_pushbuf_flag == 0) { 331 qip->qli_pushbuf_flag = 1; 332 ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno); 333#ifdef DEBUG 334 qip->qli_push_owner = current_pid(); 335#endif 336 /* 337 * The dquot is left locked. 338 */ 339 retval = XFS_ITEM_PUSHBUF; 340 } else { 341 retval = XFS_ITEM_FLUSHING; 342 xfs_dqunlock_nonotify(dqp); 343 } 344 } 345 346 ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL); 347 return (retval); 348} 349 350 351/* 352 * Unlock the dquot associated with the log item. 353 * Clear the fields of the dquot and dquot log item that 354 * are specific to the current transaction. If the 355 * hold flags is set, do not unlock the dquot. 356 */ 357STATIC void 358xfs_qm_dquot_logitem_unlock( 359 xfs_dq_logitem_t *ql) 360{ 361 xfs_dquot_t *dqp; 362 363 ASSERT(ql != NULL); 364 dqp = ql->qli_dquot; 365 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 366 367 /* 368 * Clear the transaction pointer in the dquot 369 */ 370 dqp->q_transp = NULL; 371 372 /* 373 * dquots are never 'held' from getting unlocked at the end of 374 * a transaction. Their locking and unlocking is hidden inside the 375 * transaction layer, within trans_commit. Hence, no LI_HOLD flag 376 * for the logitem. 377 */ 378 xfs_dqunlock(dqp); 379} 380 381 382/* 383 * this needs to stamp an lsn into the dquot, I think. 384 * rpc's that look at user dquot's would then have to 385 * push on the dependency recorded in the dquot 386 */ 387/* ARGSUSED */ 388STATIC void 389xfs_qm_dquot_logitem_committing( 390 xfs_dq_logitem_t *l, 391 xfs_lsn_t lsn) 392{ 393 return; 394} 395 396 397/* 398 * This is the ops vector for dquots 399 */ 400static struct xfs_item_ops xfs_dquot_item_ops = { 401 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, 402 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 403 xfs_qm_dquot_logitem_format, 404 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin, 405 .iop_unpin = (void(*)(xfs_log_item_t*, int)) 406 xfs_qm_dquot_logitem_unpin, 407 .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) 408 xfs_qm_dquot_logitem_unpin_remove, 409 .iop_trylock = (uint(*)(xfs_log_item_t*)) 410 xfs_qm_dquot_logitem_trylock, 411 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unlock, 412 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) 413 xfs_qm_dquot_logitem_committed, 414 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push, 415 .iop_pushbuf = (void(*)(xfs_log_item_t*)) 416 xfs_qm_dquot_logitem_pushbuf, 417 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) 418 xfs_qm_dquot_logitem_committing 419}; 420 421/* 422 * Initialize the dquot log item for a newly allocated dquot. 423 * The dquot isn't locked at this point, but it isn't on any of the lists 424 * either, so we don't care. 425 */ 426void 427xfs_qm_dquot_logitem_init( 428 struct xfs_dquot *dqp) 429{ 430 xfs_dq_logitem_t *lp; 431 lp = &dqp->q_logitem; 432 433 lp->qli_item.li_type = XFS_LI_DQUOT; 434 lp->qli_item.li_ops = &xfs_dquot_item_ops; 435 lp->qli_item.li_mountp = dqp->q_mount; 436 lp->qli_dquot = dqp; 437 lp->qli_format.qlf_type = XFS_LI_DQUOT; 438 lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id); 439 lp->qli_format.qlf_blkno = dqp->q_blkno; 440 lp->qli_format.qlf_len = 1; 441 /* 442 * This is just the offset of this dquot within its buffer 443 * (which is currently 1 FSB and probably won't change). 444 * Hence 32 bits for this offset should be just fine. 445 * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t)) 446 * here, and recompute it at recovery time. 447 */ 448 lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset; 449} 450 451/*------------------ QUOTAOFF LOG ITEMS -------------------*/ 452 453/* 454 * This returns the number of iovecs needed to log the given quotaoff item. 455 * We only need 1 iovec for an quotaoff item. It just logs the 456 * quotaoff_log_format structure. 457 */ 458/*ARGSUSED*/ 459STATIC uint 460xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf) 461{ 462 return (1); 463} 464 465/* 466 * This is called to fill in the vector of log iovecs for the 467 * given quotaoff log item. We use only 1 iovec, and we point that 468 * at the quotaoff_log_format structure embedded in the quotaoff item. 469 * It is at this point that we assert that all of the extent 470 * slots in the quotaoff item have been filled. 471 */ 472STATIC void 473xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf, 474 xfs_log_iovec_t *log_vector) 475{ 476 ASSERT(qf->qql_format.qf_type == XFS_LI_QUOTAOFF); 477 478 log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); 479 log_vector->i_len = sizeof(xfs_qoff_logitem_t); 480 XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF); 481 qf->qql_format.qf_size = 1; 482} 483 484 485/* 486 * Pinning has no meaning for an quotaoff item, so just return. 487 */ 488/*ARGSUSED*/ 489STATIC void 490xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf) 491{ 492 return; 493} 494 495 496/* 497 * Since pinning has no meaning for an quotaoff item, unpinning does 498 * not either. 499 */ 500/*ARGSUSED*/ 501STATIC void 502xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale) 503{ 504 return; 505} 506 507/*ARGSUSED*/ 508STATIC void 509xfs_qm_qoff_logitem_unpin_remove(xfs_qoff_logitem_t *qf, xfs_trans_t *tp) 510{ 511 return; 512} 513 514/* 515 * Quotaoff items have no locking, so just return success. 516 */ 517/*ARGSUSED*/ 518STATIC uint 519xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf) 520{ 521 return XFS_ITEM_LOCKED; 522} 523 524/* 525 * Quotaoff items have no locking or pushing, so return failure 526 * so that the caller doesn't bother with us. 527 */ 528/*ARGSUSED*/ 529STATIC void 530xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t *qf) 531{ 532 return; 533} 534 535/* 536 * The quotaoff-start-item is logged only once and cannot be moved in the log, 537 * so simply return the lsn at which it's been logged. 538 */ 539/*ARGSUSED*/ 540STATIC xfs_lsn_t 541xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn) 542{ 543 return (lsn); 544} 545 546/* 547 * There isn't much you can do to push on an quotaoff item. It is simply 548 * stuck waiting for the log to be flushed to disk. 549 */ 550/*ARGSUSED*/ 551STATIC void 552xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf) 553{ 554 return; 555} 556 557 558/*ARGSUSED*/ 559STATIC xfs_lsn_t 560xfs_qm_qoffend_logitem_committed( 561 xfs_qoff_logitem_t *qfe, 562 xfs_lsn_t lsn) 563{ 564 xfs_qoff_logitem_t *qfs; 565 SPLDECL(s); 566 567 qfs = qfe->qql_start_lip; 568 AIL_LOCK(qfs->qql_item.li_mountp,s); 569 /* 570 * Delete the qoff-start logitem from the AIL. 571 * xfs_trans_delete_ail() drops the AIL lock. 572 */ 573 xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs, s); 574 kmem_free(qfs, sizeof(xfs_qoff_logitem_t)); 575 kmem_free(qfe, sizeof(xfs_qoff_logitem_t)); 576 return (xfs_lsn_t)-1; 577} 578 579/* ARGSUSED */ 580STATIC void 581xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn) 582{ 583 return; 584} 585 586/* ARGSUSED */ 587STATIC void 588xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn) 589{ 590 return; 591} 592 593static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 594 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 595 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 596 xfs_qm_qoff_logitem_format, 597 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, 598 .iop_unpin = (void(*)(xfs_log_item_t* ,int)) 599 xfs_qm_qoff_logitem_unpin, 600 .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) 601 xfs_qm_qoff_logitem_unpin_remove, 602 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, 603 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock, 604 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) 605 xfs_qm_qoffend_logitem_committed, 606 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, 607 .iop_pushbuf = NULL, 608 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) 609 xfs_qm_qoffend_logitem_committing 610}; 611 612/* 613 * This is the ops vector shared by all quotaoff-start log items. 614 */ 615static struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 616 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 617 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 618 xfs_qm_qoff_logitem_format, 619 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, 620 .iop_unpin = (void(*)(xfs_log_item_t*, int)) 621 xfs_qm_qoff_logitem_unpin, 622 .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) 623 xfs_qm_qoff_logitem_unpin_remove, 624 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, 625 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock, 626 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) 627 xfs_qm_qoff_logitem_committed, 628 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, 629 .iop_pushbuf = NULL, 630 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) 631 xfs_qm_qoff_logitem_committing 632}; 633 634/* 635 * Allocate and initialize an quotaoff item of the correct quota type(s). 636 */ 637xfs_qoff_logitem_t * 638xfs_qm_qoff_logitem_init( 639 struct xfs_mount *mp, 640 xfs_qoff_logitem_t *start, 641 uint flags) 642{ 643 xfs_qoff_logitem_t *qf; 644 645 qf = (xfs_qoff_logitem_t*) kmem_zalloc(sizeof(xfs_qoff_logitem_t), KM_SLEEP); 646 647 qf->qql_item.li_type = XFS_LI_QUOTAOFF; 648 if (start) 649 qf->qql_item.li_ops = &xfs_qm_qoffend_logitem_ops; 650 else 651 qf->qql_item.li_ops = &xfs_qm_qoff_logitem_ops; 652 qf->qql_item.li_mountp = mp; 653 qf->qql_format.qf_type = XFS_LI_QUOTAOFF; 654 qf->qql_format.qf_flags = flags; 655 qf->qql_start_lip = start; 656 return (qf); 657} 658