···4040#include "xfs_rw.h"4141#include "xfs_iomap.h"4242#include <linux/mpage.h>4343+#include <linux/pagevec.h>4344#include <linux/writeback.h>44454546STATIC void xfs_count_page_state(struct page *, int *, int *, int *);4646-STATIC void xfs_convert_page(struct inode *, struct page *, xfs_iomap_t *,4747- struct writeback_control *wbc, void *, int, int);48474948#if defined(XFS_RW_TRACE)5049void···5455 int mask)5556{5657 xfs_inode_t *ip;5757- bhv_desc_t *bdp;5858 vnode_t *vp = LINVFS_GET_VP(inode);5959 loff_t isize = i_size_read(inode);6060- loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;6060+ loff_t offset = page_offset(page);6161 int delalloc = -1, unmapped = -1, unwritten = -1;62626363 if (page_has_buffers(page))6464 xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);65656666- bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);6767- ip = XFS_BHVTOI(bdp);6666+ ip = xfs_vtoi(vp);6867 if (!ip->i_rwtrace)6968 return;7069···100103 queue_work(xfsdatad_workqueue, &ioend->io_work);101104}102105106106+/*107107+ * We're now finished for good with this ioend structure.108108+ * Update the page state via the associated buffer_heads,109109+ * release holds on the inode and bio, and finally free110110+ * up memory. Do not use the ioend after this.111111+ */103112STATIC void104113xfs_destroy_ioend(105114 xfs_ioend_t *ioend)106115{116116+ struct buffer_head *bh, *next;117117+118118+ for (bh = ioend->io_buffer_head; bh; bh = next) {119119+ next = bh->b_private;120120+ bh->b_end_io(bh, ioend->io_uptodate);121121+ }122122+107123 vn_iowake(ioend->io_vnode);108124 mempool_free(ioend, xfs_ioend_pool);109125}110126111127/*128128+ * Buffered IO write completion for delayed allocate extents.129129+ * TODO: Update ondisk isize now that we know the file data130130+ * has been flushed (i.e. the notorious "NULL file" problem).131131+ */132132+STATIC void133133+xfs_end_bio_delalloc(134134+ void *data)135135+{136136+ xfs_ioend_t *ioend = data;137137+138138+ xfs_destroy_ioend(ioend);139139+}140140+141141+/*142142+ * Buffered IO write completion for regular, written extents.143143+ */144144+STATIC void145145+xfs_end_bio_written(146146+ void *data)147147+{148148+ xfs_ioend_t *ioend = data;149149+150150+ xfs_destroy_ioend(ioend);151151+}152152+153153+/*154154+ * IO write completion for unwritten extents.155155+ *112156 * Issue transactions to convert a buffer range from unwritten113157 * to written extents.114158 */···161123 vnode_t *vp = ioend->io_vnode;162124 xfs_off_t offset = ioend->io_offset;163125 size_t size = ioend->io_size;164164- struct buffer_head *bh, *next;165126 int error;166127167128 if (ioend->io_uptodate)168129 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);169169-170170- /* ioend->io_buffer_head is only non-NULL for buffered I/O */171171- for (bh = ioend->io_buffer_head; bh; bh = next) {172172- next = bh->b_private;173173-174174- bh->b_end_io = NULL;175175- clear_buffer_unwritten(bh);176176- end_buffer_async_write(bh, ioend->io_uptodate);177177- }178178-179130 xfs_destroy_ioend(ioend);180131}181132···176149 */177150STATIC xfs_ioend_t *178151xfs_alloc_ioend(179179- struct inode *inode)152152+ struct inode *inode,153153+ unsigned int type)180154{181155 xfs_ioend_t *ioend;182156···190162 */191163 atomic_set(&ioend->io_remaining, 1);192164 ioend->io_uptodate = 1; /* cleared if any I/O fails */165165+ ioend->io_list = NULL;166166+ ioend->io_type = type;193167 ioend->io_vnode = LINVFS_GET_VP(inode);194168 ioend->io_buffer_head = NULL;169169+ ioend->io_buffer_tail = NULL;195170 atomic_inc(&ioend->io_vnode->v_iocount);196171 ioend->io_offset = 0;197172 ioend->io_size = 0;198173199199- INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend);174174+ if (type == IOMAP_UNWRITTEN)175175+ INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend);176176+ else if (type == IOMAP_DELAY)177177+ INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc, ioend);178178+ else179179+ INIT_WORK(&ioend->io_work, xfs_end_bio_written, ioend);200180201181 return ioend;202202-}203203-204204-void205205-linvfs_unwritten_done(206206- struct buffer_head *bh,207207- int uptodate)208208-{209209- xfs_ioend_t *ioend = bh->b_private;210210- static spinlock_t unwritten_done_lock = SPIN_LOCK_UNLOCKED;211211- unsigned long flags;212212-213213- ASSERT(buffer_unwritten(bh));214214- bh->b_end_io = NULL;215215-216216- if (!uptodate)217217- ioend->io_uptodate = 0;218218-219219- /*220220- * Deep magic here. We reuse b_private in the buffer_heads to build221221- * a chain for completing the I/O from user context after we've issued222222- * a transaction to convert the unwritten extent.223223- */224224- spin_lock_irqsave(&unwritten_done_lock, flags);225225- bh->b_private = ioend->io_buffer_head;226226- ioend->io_buffer_head = bh;227227- spin_unlock_irqrestore(&unwritten_done_lock, flags);228228-229229- xfs_finish_ioend(ioend);230182}231183232184STATIC int···226218 return -error;227219}228220229229-/*230230- * Finds the corresponding mapping in block @map array of the231231- * given @offset within a @page.232232- */233233-STATIC xfs_iomap_t *234234-xfs_offset_to_map(235235- struct page *page,221221+STATIC inline int222222+xfs_iomap_valid(236223 xfs_iomap_t *iomapp,237237- unsigned long offset)224224+ loff_t offset)238225{239239- loff_t full_offset; /* offset from start of file */226226+ return offset >= iomapp->iomap_offset &&227227+ offset < iomapp->iomap_offset + iomapp->iomap_bsize;228228+}240229241241- ASSERT(offset < PAGE_CACHE_SIZE);230230+/*231231+ * BIO completion handler for buffered IO.232232+ */233233+STATIC int234234+xfs_end_bio(235235+ struct bio *bio,236236+ unsigned int bytes_done,237237+ int error)238238+{239239+ xfs_ioend_t *ioend = bio->bi_private;242240243243- full_offset = page->index; /* NB: using 64bit number */244244- full_offset <<= PAGE_CACHE_SHIFT; /* offset from file start */245245- full_offset += offset; /* offset from page start */241241+ if (bio->bi_size)242242+ return 1;246243247247- if (full_offset < iomapp->iomap_offset)248248- return NULL;249249- if (iomapp->iomap_offset + (iomapp->iomap_bsize -1) >= full_offset)250250- return iomapp;251251- return NULL;244244+ ASSERT(ioend);245245+ ASSERT(atomic_read(&bio->bi_cnt) >= 1);246246+247247+ /* Toss bio and pass work off to an xfsdatad thread */248248+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags))249249+ ioend->io_uptodate = 0;250250+ bio->bi_private = NULL;251251+ bio->bi_end_io = NULL;252252+253253+ bio_put(bio);254254+ xfs_finish_ioend(ioend);255255+ return 0;256256+}257257+258258+STATIC void259259+xfs_submit_ioend_bio(260260+ xfs_ioend_t *ioend,261261+ struct bio *bio)262262+{263263+ atomic_inc(&ioend->io_remaining);264264+265265+ bio->bi_private = ioend;266266+ bio->bi_end_io = xfs_end_bio;267267+268268+ submit_bio(WRITE, bio);269269+ ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));270270+ bio_put(bio);271271+}272272+273273+STATIC struct bio *274274+xfs_alloc_ioend_bio(275275+ struct buffer_head *bh)276276+{277277+ struct bio *bio;278278+ int nvecs = bio_get_nr_vecs(bh->b_bdev);279279+280280+ do {281281+ bio = bio_alloc(GFP_NOIO, nvecs);282282+ nvecs >>= 1;283283+ } while (!bio);284284+285285+ ASSERT(bio->bi_private == NULL);286286+ bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);287287+ bio->bi_bdev = bh->b_bdev;288288+ bio_get(bio);289289+ return bio;290290+}291291+292292+STATIC void293293+xfs_start_buffer_writeback(294294+ struct buffer_head *bh)295295+{296296+ ASSERT(buffer_mapped(bh));297297+ ASSERT(buffer_locked(bh));298298+ ASSERT(!buffer_delay(bh));299299+ ASSERT(!buffer_unwritten(bh));300300+301301+ mark_buffer_async_write(bh);302302+ set_buffer_uptodate(bh);303303+ clear_buffer_dirty(bh);304304+}305305+306306+STATIC void307307+xfs_start_page_writeback(308308+ struct page *page,309309+ struct writeback_control *wbc,310310+ int clear_dirty,311311+ int buffers)312312+{313313+ ASSERT(PageLocked(page));314314+ ASSERT(!PageWriteback(page));315315+ set_page_writeback(page);316316+ if (clear_dirty)317317+ clear_page_dirty(page);318318+ unlock_page(page);319319+ if (!buffers) {320320+ end_page_writeback(page);321321+ wbc->pages_skipped++; /* We didn't write this page */322322+ }323323+}324324+325325+static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)326326+{327327+ return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));328328+}329329+330330+/*331331+ * Submit all of the bios for all of the ioends we have saved up,332332+ * covering the initial writepage page and also any probed pages.333333+ */334334+STATIC void335335+xfs_submit_ioend(336336+ xfs_ioend_t *ioend)337337+{338338+ xfs_ioend_t *next;339339+ struct buffer_head *bh;340340+ struct bio *bio;341341+ sector_t lastblock = 0;342342+343343+ do {344344+ next = ioend->io_list;345345+ bio = NULL;346346+347347+ for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {348348+ xfs_start_buffer_writeback(bh);349349+350350+ if (!bio) {351351+ retry:352352+ bio = xfs_alloc_ioend_bio(bh);353353+ } else if (bh->b_blocknr != lastblock + 1) {354354+ xfs_submit_ioend_bio(ioend, bio);355355+ goto retry;356356+ }357357+358358+ if (bio_add_buffer(bio, bh) != bh->b_size) {359359+ xfs_submit_ioend_bio(ioend, bio);360360+ goto retry;361361+ }362362+363363+ lastblock = bh->b_blocknr;364364+ }365365+ if (bio)366366+ xfs_submit_ioend_bio(ioend, bio);367367+ xfs_finish_ioend(ioend);368368+ } while ((ioend = next) != NULL);369369+}370370+371371+/*372372+ * Cancel submission of all buffer_heads so far in this endio.373373+ * Toss the endio too. Only ever called for the initial page374374+ * in a writepage request, so only ever one page.375375+ */376376+STATIC void377377+xfs_cancel_ioend(378378+ xfs_ioend_t *ioend)379379+{380380+ xfs_ioend_t *next;381381+ struct buffer_head *bh, *next_bh;382382+383383+ do {384384+ next = ioend->io_list;385385+ bh = ioend->io_buffer_head;386386+ do {387387+ next_bh = bh->b_private;388388+ clear_buffer_async_write(bh);389389+ unlock_buffer(bh);390390+ } while ((bh = next_bh) != NULL);391391+392392+ vn_iowake(ioend->io_vnode);393393+ mempool_free(ioend, xfs_ioend_pool);394394+ } while ((ioend = next) != NULL);395395+}396396+397397+/*398398+ * Test to see if we've been building up a completion structure for399399+ * earlier buffers -- if so, we try to append to this ioend if we400400+ * can, otherwise we finish off any current ioend and start another.401401+ * Return true if we've finished the given ioend.402402+ */403403+STATIC void404404+xfs_add_to_ioend(405405+ struct inode *inode,406406+ struct buffer_head *bh,407407+ xfs_off_t offset,408408+ unsigned int type,409409+ xfs_ioend_t **result,410410+ int need_ioend)411411+{412412+ xfs_ioend_t *ioend = *result;413413+414414+ if (!ioend || need_ioend || type != ioend->io_type) {415415+ xfs_ioend_t *previous = *result;416416+417417+ ioend = xfs_alloc_ioend(inode, type);418418+ ioend->io_offset = offset;419419+ ioend->io_buffer_head = bh;420420+ ioend->io_buffer_tail = bh;421421+ if (previous)422422+ previous->io_list = ioend;423423+ *result = ioend;424424+ } else {425425+ ioend->io_buffer_tail->b_private = bh;426426+ ioend->io_buffer_tail = bh;427427+ }428428+429429+ bh->b_private = NULL;430430+ ioend->io_size += bh->b_size;252431}253432254433STATIC void255434xfs_map_at_offset(256256- struct page *page,257435 struct buffer_head *bh,258258- unsigned long offset,436436+ loff_t offset,259437 int block_bits,260438 xfs_iomap_t *iomapp)261439{262440 xfs_daddr_t bn;263263- loff_t delta;264441 int sector_shift;265442266443 ASSERT(!(iomapp->iomap_flags & IOMAP_HOLE));267444 ASSERT(!(iomapp->iomap_flags & IOMAP_DELAY));268445 ASSERT(iomapp->iomap_bn != IOMAP_DADDR_NULL);269446270270- delta = page->index;271271- delta <<= PAGE_CACHE_SHIFT;272272- delta += offset;273273- delta -= iomapp->iomap_offset;274274- delta >>= block_bits;275275-276447 sector_shift = block_bits - BBSHIFT;277277- bn = iomapp->iomap_bn >> sector_shift;278278- bn += delta;279279- BUG_ON(!bn && !(iomapp->iomap_flags & IOMAP_REALTIME));448448+ bn = (iomapp->iomap_bn >> sector_shift) +449449+ ((offset - iomapp->iomap_offset) >> block_bits);450450+451451+ ASSERT(bn || (iomapp->iomap_flags & IOMAP_REALTIME));280452 ASSERT((bn << sector_shift) >= iomapp->iomap_bn);281453282454 lock_buffer(bh);283455 bh->b_blocknr = bn;284284- bh->b_bdev = iomapp->iomap_target->pbr_bdev;456456+ bh->b_bdev = iomapp->iomap_target->bt_bdev;285457 set_buffer_mapped(bh);286458 clear_buffer_delay(bh);459459+ clear_buffer_unwritten(bh);287460}288461289462/*290290- * Look for a page at index which is unlocked and contains our291291- * unwritten extent flagged buffers at its head. Returns page292292- * locked and with an extra reference count, and length of the293293- * unwritten extent component on this page that we can write,294294- * in units of filesystem blocks.295295- */296296-STATIC struct page *297297-xfs_probe_unwritten_page(298298- struct address_space *mapping,299299- pgoff_t index,300300- xfs_iomap_t *iomapp,301301- xfs_ioend_t *ioend,302302- unsigned long max_offset,303303- unsigned long *fsbs,304304- unsigned int bbits)305305-{306306- struct page *page;307307-308308- page = find_trylock_page(mapping, index);309309- if (!page)310310- return NULL;311311- if (PageWriteback(page))312312- goto out;313313-314314- if (page->mapping && page_has_buffers(page)) {315315- struct buffer_head *bh, *head;316316- unsigned long p_offset = 0;317317-318318- *fsbs = 0;319319- bh = head = page_buffers(page);320320- do {321321- if (!buffer_unwritten(bh) || !buffer_uptodate(bh))322322- break;323323- if (!xfs_offset_to_map(page, iomapp, p_offset))324324- break;325325- if (p_offset >= max_offset)326326- break;327327- xfs_map_at_offset(page, bh, p_offset, bbits, iomapp);328328- set_buffer_unwritten_io(bh);329329- bh->b_private = ioend;330330- p_offset += bh->b_size;331331- (*fsbs)++;332332- } while ((bh = bh->b_this_page) != head);333333-334334- if (p_offset)335335- return page;336336- }337337-338338-out:339339- unlock_page(page);340340- return NULL;341341-}342342-343343-/*344344- * Look for a page at index which is unlocked and not mapped345345- * yet - clustering for mmap write case.463463+ * Look for a page at index that is suitable for clustering.346464 */347465STATIC unsigned int348348-xfs_probe_unmapped_page(349349- struct address_space *mapping,350350- pgoff_t index,351351- unsigned int pg_offset)466466+xfs_probe_page(467467+ struct page *page,468468+ unsigned int pg_offset,469469+ int mapped)352470{353353- struct page *page;354471 int ret = 0;355472356356- page = find_trylock_page(mapping, index);357357- if (!page)358358- return 0;359473 if (PageWriteback(page))360360- goto out;474474+ return 0;361475362476 if (page->mapping && PageDirty(page)) {363477 if (page_has_buffers(page)) {···487357488358 bh = head = page_buffers(page);489359 do {490490- if (buffer_mapped(bh) || !buffer_uptodate(bh))360360+ if (!buffer_uptodate(bh))361361+ break;362362+ if (mapped != buffer_mapped(bh))491363 break;492364 ret += bh->b_size;493365 if (ret >= pg_offset)494366 break;495367 } while ((bh = bh->b_this_page) != head);496368 } else497497- ret = PAGE_CACHE_SIZE;369369+ ret = mapped ? 0 : PAGE_CACHE_SIZE;498370 }499371500500-out:501501- unlock_page(page);502372 return ret;503373}504374505505-STATIC unsigned int506506-xfs_probe_unmapped_cluster(375375+STATIC size_t376376+xfs_probe_cluster(507377 struct inode *inode,508378 struct page *startpage,509379 struct buffer_head *bh,510510- struct buffer_head *head)380380+ struct buffer_head *head,381381+ int mapped)511382{383383+ struct pagevec pvec;512384 pgoff_t tindex, tlast, tloff;513513- unsigned int pg_offset, len, total = 0;514514- struct address_space *mapping = inode->i_mapping;385385+ size_t total = 0;386386+ int done = 0, i;515387516388 /* First sum forwards in this page */517389 do {518518- if (buffer_mapped(bh))519519- break;390390+ if (mapped != buffer_mapped(bh))391391+ return total;520392 total += bh->b_size;521393 } while ((bh = bh->b_this_page) != head);522394523523- /* If we reached the end of the page, sum forwards in524524- * following pages.525525- */526526- if (bh == head) {527527- tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;528528- /* Prune this back to avoid pathological behavior */529529- tloff = min(tlast, startpage->index + 64);530530- for (tindex = startpage->index + 1; tindex < tloff; tindex++) {531531- len = xfs_probe_unmapped_page(mapping, tindex,532532- PAGE_CACHE_SIZE);533533- if (!len)534534- return total;395395+ /* if we reached the end of the page, sum forwards in following pages */396396+ tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;397397+ tindex = startpage->index + 1;398398+399399+ /* Prune this back to avoid pathological behavior */400400+ tloff = min(tlast, startpage->index + 64);401401+402402+ pagevec_init(&pvec, 0);403403+ while (!done && tindex <= tloff) {404404+ unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);405405+406406+ if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))407407+ break;408408+409409+ for (i = 0; i < pagevec_count(&pvec); i++) {410410+ struct page *page = pvec.pages[i];411411+ size_t pg_offset, len = 0;412412+413413+ if (tindex == tlast) {414414+ pg_offset =415415+ i_size_read(inode) & (PAGE_CACHE_SIZE - 1);416416+ if (!pg_offset) {417417+ done = 1;418418+ break;419419+ }420420+ } else421421+ pg_offset = PAGE_CACHE_SIZE;422422+423423+ if (page->index == tindex && !TestSetPageLocked(page)) {424424+ len = xfs_probe_page(page, pg_offset, mapped);425425+ unlock_page(page);426426+ }427427+428428+ if (!len) {429429+ done = 1;430430+ break;431431+ }432432+535433 total += len;434434+ tindex++;536435 }537537- if (tindex == tlast &&538538- (pg_offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {539539- total += xfs_probe_unmapped_page(mapping,540540- tindex, pg_offset);541541- }436436+437437+ pagevec_release(&pvec);438438+ cond_resched();542439 }440440+543441 return total;544442}545443546444/*547547- * Probe for a given page (index) in the inode and test if it is delayed548548- * and without unwritten buffers. Returns page locked and with an extra549549- * reference count.445445+ * Test if a given page is suitable for writing as part of an unwritten446446+ * or delayed allocate extent.550447 */551551-STATIC struct page *552552-xfs_probe_delalloc_page(553553- struct inode *inode,554554- pgoff_t index)448448+STATIC int449449+xfs_is_delayed_page(450450+ struct page *page,451451+ unsigned int type)555452{556556- struct page *page;557557-558558- page = find_trylock_page(inode->i_mapping, index);559559- if (!page)560560- return NULL;561453 if (PageWriteback(page))562562- goto out;454454+ return 0;563455564456 if (page->mapping && page_has_buffers(page)) {565457 struct buffer_head *bh, *head;···589437590438 bh = head = page_buffers(page);591439 do {592592- if (buffer_unwritten(bh)) {593593- acceptable = 0;440440+ if (buffer_unwritten(bh))441441+ acceptable = (type == IOMAP_UNWRITTEN);442442+ else if (buffer_delay(bh))443443+ acceptable = (type == IOMAP_DELAY);444444+ else if (buffer_mapped(bh))445445+ acceptable = (type == 0);446446+ else594447 break;595595- } else if (buffer_delay(bh)) {596596- acceptable = 1;597597- }598448 } while ((bh = bh->b_this_page) != head);599449600450 if (acceptable)601601- return page;451451+ return 1;602452 }603453604604-out:605605- unlock_page(page);606606- return NULL;607607-}608608-609609-STATIC int610610-xfs_map_unwritten(611611- struct inode *inode,612612- struct page *start_page,613613- struct buffer_head *head,614614- struct buffer_head *curr,615615- unsigned long p_offset,616616- int block_bits,617617- xfs_iomap_t *iomapp,618618- struct writeback_control *wbc,619619- int startio,620620- int all_bh)621621-{622622- struct buffer_head *bh = curr;623623- xfs_iomap_t *tmp;624624- xfs_ioend_t *ioend;625625- loff_t offset;626626- unsigned long nblocks = 0;627627-628628- offset = start_page->index;629629- offset <<= PAGE_CACHE_SHIFT;630630- offset += p_offset;631631-632632- ioend = xfs_alloc_ioend(inode);633633-634634- /* First map forwards in the page consecutive buffers635635- * covering this unwritten extent636636- */637637- do {638638- if (!buffer_unwritten(bh))639639- break;640640- tmp = xfs_offset_to_map(start_page, iomapp, p_offset);641641- if (!tmp)642642- break;643643- xfs_map_at_offset(start_page, bh, p_offset, block_bits, iomapp);644644- set_buffer_unwritten_io(bh);645645- bh->b_private = ioend;646646- p_offset += bh->b_size;647647- nblocks++;648648- } while ((bh = bh->b_this_page) != head);649649-650650- atomic_add(nblocks, &ioend->io_remaining);651651-652652- /* If we reached the end of the page, map forwards in any653653- * following pages which are also covered by this extent.654654- */655655- if (bh == head) {656656- struct address_space *mapping = inode->i_mapping;657657- pgoff_t tindex, tloff, tlast;658658- unsigned long bs;659659- unsigned int pg_offset, bbits = inode->i_blkbits;660660- struct page *page;661661-662662- tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;663663- tloff = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;664664- tloff = min(tlast, tloff);665665- for (tindex = start_page->index + 1; tindex < tloff; tindex++) {666666- page = xfs_probe_unwritten_page(mapping,667667- tindex, iomapp, ioend,668668- PAGE_CACHE_SIZE, &bs, bbits);669669- if (!page)670670- break;671671- nblocks += bs;672672- atomic_add(bs, &ioend->io_remaining);673673- xfs_convert_page(inode, page, iomapp, wbc, ioend,674674- startio, all_bh);675675- /* stop if converting the next page might add676676- * enough blocks that the corresponding byte677677- * count won't fit in our ulong page buf length */678678- if (nblocks >= ((ULONG_MAX - PAGE_SIZE) >> block_bits))679679- goto enough;680680- }681681-682682- if (tindex == tlast &&683683- (pg_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {684684- page = xfs_probe_unwritten_page(mapping,685685- tindex, iomapp, ioend,686686- pg_offset, &bs, bbits);687687- if (page) {688688- nblocks += bs;689689- atomic_add(bs, &ioend->io_remaining);690690- xfs_convert_page(inode, page, iomapp, wbc, ioend,691691- startio, all_bh);692692- if (nblocks >= ((ULONG_MAX - PAGE_SIZE) >> block_bits))693693- goto enough;694694- }695695- }696696- }697697-698698-enough:699699- ioend->io_size = (xfs_off_t)nblocks << block_bits;700700- ioend->io_offset = offset;701701- xfs_finish_ioend(ioend);702454 return 0;703703-}704704-705705-STATIC void706706-xfs_submit_page(707707- struct page *page,708708- struct writeback_control *wbc,709709- struct buffer_head *bh_arr[],710710- int bh_count,711711- int probed_page,712712- int clear_dirty)713713-{714714- struct buffer_head *bh;715715- int i;716716-717717- BUG_ON(PageWriteback(page));718718- if (bh_count)719719- set_page_writeback(page);720720- if (clear_dirty)721721- clear_page_dirty(page);722722- unlock_page(page);723723-724724- if (bh_count) {725725- for (i = 0; i < bh_count; i++) {726726- bh = bh_arr[i];727727- mark_buffer_async_write(bh);728728- if (buffer_unwritten(bh))729729- set_buffer_unwritten_io(bh);730730- set_buffer_uptodate(bh);731731- clear_buffer_dirty(bh);732732- }733733-734734- for (i = 0; i < bh_count; i++)735735- submit_bh(WRITE, bh_arr[i]);736736-737737- if (probed_page && clear_dirty)738738- wbc->nr_to_write--; /* Wrote an "extra" page */739739- }740455}741456742457/*···612593 * delalloc/unwritten pages only, for the original page it is possible613594 * that the page has no mapping at all.614595 */615615-STATIC void596596+STATIC int616597xfs_convert_page(617598 struct inode *inode,618599 struct page *page,619619- xfs_iomap_t *iomapp,600600+ loff_t tindex,601601+ xfs_iomap_t *mp,602602+ xfs_ioend_t **ioendp,620603 struct writeback_control *wbc,621621- void *private,622604 int startio,623605 int all_bh)624606{625625- struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;626626- xfs_iomap_t *mp = iomapp, *tmp;627627- unsigned long offset, end_offset;628628- int index = 0;607607+ struct buffer_head *bh, *head;608608+ xfs_off_t end_offset;609609+ unsigned long p_offset;610610+ unsigned int type;629611 int bbits = inode->i_blkbits;630612 int len, page_dirty;613613+ int count = 0, done = 0, uptodate = 1;614614+ xfs_off_t offset = page_offset(page);631615632632- end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));616616+ if (page->index != tindex)617617+ goto fail;618618+ if (TestSetPageLocked(page))619619+ goto fail;620620+ if (PageWriteback(page))621621+ goto fail_unlock_page;622622+ if (page->mapping != inode->i_mapping)623623+ goto fail_unlock_page;624624+ if (!xfs_is_delayed_page(page, (*ioendp)->io_type))625625+ goto fail_unlock_page;633626634627 /*635628 * page_dirty is initially a count of buffers on the page before636629 * EOF and is decrememted as we move each into a cleanable state.630630+ *631631+ * Derivation:632632+ *633633+ * End offset is the highest offset that this page should represent.634634+ * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))635635+ * will evaluate non-zero and be less than PAGE_CACHE_SIZE and636636+ * hence give us the correct page_dirty count. On any other page,637637+ * it will be zero and in that case we need page_dirty to be the638638+ * count of buffers on the page.637639 */638638- len = 1 << inode->i_blkbits;639639- end_offset = max(end_offset, PAGE_CACHE_SIZE);640640- end_offset = roundup(end_offset, len);641641- page_dirty = end_offset / len;640640+ end_offset = min_t(unsigned long long,641641+ (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,642642+ i_size_read(inode));642643643643- offset = 0;644644+ len = 1 << inode->i_blkbits;645645+ p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),646646+ PAGE_CACHE_SIZE);647647+ p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;648648+ page_dirty = p_offset / len;649649+644650 bh = head = page_buffers(page);645651 do {646652 if (offset >= end_offset)647653 break;648648- if (!(PageUptodate(page) || buffer_uptodate(bh)))649649- continue;650650- if (buffer_mapped(bh) && all_bh &&651651- !(buffer_unwritten(bh) || buffer_delay(bh))) {652652- if (startio) {653653- lock_buffer(bh);654654- bh_arr[index++] = bh;655655- page_dirty--;656656- }654654+ if (!buffer_uptodate(bh))655655+ uptodate = 0;656656+ if (!(PageUptodate(page) || buffer_uptodate(bh))) {657657+ done = 1;657658 continue;658659 }659659- tmp = xfs_offset_to_map(page, mp, offset);660660- if (!tmp)661661- continue;662662- ASSERT(!(tmp->iomap_flags & IOMAP_HOLE));663663- ASSERT(!(tmp->iomap_flags & IOMAP_DELAY));664660665665- /* If this is a new unwritten extent buffer (i.e. one666666- * that we haven't passed in private data for, we must667667- * now map this buffer too.668668- */669669- if (buffer_unwritten(bh) && !bh->b_end_io) {670670- ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN);671671- xfs_map_unwritten(inode, page, head, bh, offset,672672- bbits, tmp, wbc, startio, all_bh);673673- } else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {674674- xfs_map_at_offset(page, bh, offset, bbits, tmp);675675- if (buffer_unwritten(bh)) {676676- set_buffer_unwritten_io(bh);677677- bh->b_private = private;678678- ASSERT(private);661661+ if (buffer_unwritten(bh) || buffer_delay(bh)) {662662+ if (buffer_unwritten(bh))663663+ type = IOMAP_UNWRITTEN;664664+ else665665+ type = IOMAP_DELAY;666666+667667+ if (!xfs_iomap_valid(mp, offset)) {668668+ done = 1;669669+ continue;670670+ }671671+672672+ ASSERT(!(mp->iomap_flags & IOMAP_HOLE));673673+ ASSERT(!(mp->iomap_flags & IOMAP_DELAY));674674+675675+ xfs_map_at_offset(bh, offset, bbits, mp);676676+ if (startio) {677677+ xfs_add_to_ioend(inode, bh, offset,678678+ type, ioendp, done);679679+ } else {680680+ set_buffer_dirty(bh);681681+ unlock_buffer(bh);682682+ mark_buffer_dirty(bh);683683+ }684684+ page_dirty--;685685+ count++;686686+ } else {687687+ type = 0;688688+ if (buffer_mapped(bh) && all_bh && startio) {689689+ lock_buffer(bh);690690+ xfs_add_to_ioend(inode, bh, offset,691691+ type, ioendp, done);692692+ count++;693693+ page_dirty--;694694+ } else {695695+ done = 1;679696 }680697 }681681- if (startio) {682682- bh_arr[index++] = bh;683683- } else {684684- set_buffer_dirty(bh);685685- unlock_buffer(bh);686686- mark_buffer_dirty(bh);687687- }688688- page_dirty--;689698 } while (offset += len, (bh = bh->b_this_page) != head);690699691691- if (startio && index) {692692- xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);693693- } else {694694- unlock_page(page);700700+ if (uptodate && bh == head)701701+ SetPageUptodate(page);702702+703703+ if (startio) {704704+ if (count) {705705+ struct backing_dev_info *bdi;706706+707707+ bdi = inode->i_mapping->backing_dev_info;708708+ if (bdi_write_congested(bdi)) {709709+ wbc->encountered_congestion = 1;710710+ done = 1;711711+ } else if (--wbc->nr_to_write <= 0) {712712+ done = 1;713713+ }714714+ }715715+ xfs_start_page_writeback(page, wbc, !page_dirty, count);695716 }717717+718718+ return done;719719+ fail_unlock_page:720720+ unlock_page(page);721721+ fail:722722+ return 1;696723}697724698725/*···750685 struct inode *inode,751686 pgoff_t tindex,752687 xfs_iomap_t *iomapp,688688+ xfs_ioend_t **ioendp,753689 struct writeback_control *wbc,754690 int startio,755691 int all_bh,756692 pgoff_t tlast)757693{758758- struct page *page;694694+ struct pagevec pvec;695695+ int done = 0, i;759696760760- for (; tindex <= tlast; tindex++) {761761- page = xfs_probe_delalloc_page(inode, tindex);762762- if (!page)697697+ pagevec_init(&pvec, 0);698698+ while (!done && tindex <= tlast) {699699+ unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1);700700+701701+ if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len))763702 break;764764- xfs_convert_page(inode, page, iomapp, wbc, NULL,765765- startio, all_bh);703703+704704+ for (i = 0; i < pagevec_count(&pvec); i++) {705705+ done = xfs_convert_page(inode, pvec.pages[i], tindex++,706706+ iomapp, ioendp, wbc, startio, all_bh);707707+ if (done)708708+ break;709709+ }710710+711711+ pagevec_release(&pvec);712712+ cond_resched();766713 }767714}768715···805728 int startio,806729 int unmapped) /* also implies page uptodate */807730{808808- struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;809809- xfs_iomap_t *iomp, iomap;731731+ struct buffer_head *bh, *head;732732+ xfs_iomap_t iomap;733733+ xfs_ioend_t *ioend = NULL, *iohead = NULL;810734 loff_t offset;811735 unsigned long p_offset = 0;736736+ unsigned int type;812737 __uint64_t end_offset;813738 pgoff_t end_index, last_index, tlast;814814- int len, err, i, cnt = 0, uptodate = 1;815815- int flags;816816- int page_dirty;739739+ ssize_t size, len;740740+ int flags, err, iomap_valid = 0, uptodate = 1;741741+ int page_dirty, count = 0, trylock_flag = 0;742742+ int all_bh = unmapped;817743818744 /* wait for other IO threads? */819819- flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK;745745+ if (startio && (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking))746746+ trylock_flag |= BMAPI_TRYLOCK;820747821748 /* Is this page beyond the end of the file? */822749 offset = i_size_read(inode);···835754 }836755 }837756838838- end_offset = min_t(unsigned long long,839839- (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);840840- offset = (loff_t)page->index << PAGE_CACHE_SHIFT;841841-842757 /*843758 * page_dirty is initially a count of buffers on the page before844759 * EOF and is decrememted as we move each into a cleanable state.845845- */760760+ *761761+ * Derivation:762762+ *763763+ * End offset is the highest offset that this page should represent.764764+ * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))765765+ * will evaluate non-zero and be less than PAGE_CACHE_SIZE and766766+ * hence give us the correct page_dirty count. On any other page,767767+ * it will be zero and in that case we need page_dirty to be the768768+ * count of buffers on the page.769769+ */770770+ end_offset = min_t(unsigned long long,771771+ (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);846772 len = 1 << inode->i_blkbits;847847- p_offset = max(p_offset, PAGE_CACHE_SIZE);848848- p_offset = roundup(p_offset, len);773773+ p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),774774+ PAGE_CACHE_SIZE);775775+ p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;849776 page_dirty = p_offset / len;850777851851- iomp = NULL;852852- p_offset = 0;853778 bh = head = page_buffers(page);779779+ offset = page_offset(page);780780+ flags = -1;781781+ type = 0;782782+783783+ /* TODO: cleanup count and page_dirty */854784855785 do {856786 if (offset >= end_offset)857787 break;858788 if (!buffer_uptodate(bh))859789 uptodate = 0;860860- if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio)790790+ if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) {791791+ /*792792+ * the iomap is actually still valid, but the ioend793793+ * isn't. shouldn't happen too often.794794+ */795795+ iomap_valid = 0;861796 continue;862862-863863- if (iomp) {864864- iomp = xfs_offset_to_map(page, &iomap, p_offset);865797 }798798+799799+ if (iomap_valid)800800+ iomap_valid = xfs_iomap_valid(&iomap, offset);866801867802 /*868803 * First case, map an unwritten extent and prepare for869804 * extent state conversion transaction on completion.870870- */871871- if (buffer_unwritten(bh)) {872872- if (!startio)873873- continue;874874- if (!iomp) {875875- err = xfs_map_blocks(inode, offset, len, &iomap,876876- BMAPI_WRITE|BMAPI_IGNSTATE);877877- if (err) {878878- goto error;879879- }880880- iomp = xfs_offset_to_map(page, &iomap,881881- p_offset);882882- }883883- if (iomp) {884884- if (!bh->b_end_io) {885885- err = xfs_map_unwritten(inode, page,886886- head, bh, p_offset,887887- inode->i_blkbits, iomp,888888- wbc, startio, unmapped);889889- if (err) {890890- goto error;891891- }892892- } else {893893- set_bit(BH_Lock, &bh->b_state);894894- }895895- BUG_ON(!buffer_locked(bh));896896- bh_arr[cnt++] = bh;897897- page_dirty--;898898- }899899- /*805805+ *900806 * Second case, allocate space for a delalloc buffer.901807 * We can return EAGAIN here in the release page case.902902- */903903- } else if (buffer_delay(bh)) {904904- if (!iomp) {905905- err = xfs_map_blocks(inode, offset, len, &iomap,906906- BMAPI_ALLOCATE | flags);907907- if (err) {908908- goto error;909909- }910910- iomp = xfs_offset_to_map(page, &iomap,911911- p_offset);808808+ *809809+ * Third case, an unmapped buffer was found, and we are810810+ * in a path where we need to write the whole page out.811811+ */812812+ if (buffer_unwritten(bh) || buffer_delay(bh) ||813813+ ((buffer_uptodate(bh) || PageUptodate(page)) &&814814+ !buffer_mapped(bh) && (unmapped || startio))) {815815+ /*816816+ * Make sure we don't use a read-only iomap817817+ */818818+ if (flags == BMAPI_READ)819819+ iomap_valid = 0;820820+821821+ if (buffer_unwritten(bh)) {822822+ type = IOMAP_UNWRITTEN;823823+ flags = BMAPI_WRITE|BMAPI_IGNSTATE;824824+ } else if (buffer_delay(bh)) {825825+ type = IOMAP_DELAY;826826+ flags = BMAPI_ALLOCATE;827827+ if (!startio)828828+ flags |= trylock_flag;829829+ } else {830830+ type = IOMAP_NEW;831831+ flags = BMAPI_WRITE|BMAPI_MMAP;912832 }913913- if (iomp) {914914- xfs_map_at_offset(page, bh, p_offset,915915- inode->i_blkbits, iomp);833833+834834+ if (!iomap_valid) {835835+ if (type == IOMAP_NEW) {836836+ size = xfs_probe_cluster(inode,837837+ page, bh, head, 0);838838+ } else {839839+ size = len;840840+ }841841+842842+ err = xfs_map_blocks(inode, offset, size,843843+ &iomap, flags);844844+ if (err)845845+ goto error;846846+ iomap_valid = xfs_iomap_valid(&iomap, offset);847847+ }848848+ if (iomap_valid) {849849+ xfs_map_at_offset(bh, offset,850850+ inode->i_blkbits, &iomap);916851 if (startio) {917917- bh_arr[cnt++] = bh;852852+ xfs_add_to_ioend(inode, bh, offset,853853+ type, &ioend,854854+ !iomap_valid);918855 } else {919856 set_buffer_dirty(bh);920857 unlock_buffer(bh);921858 mark_buffer_dirty(bh);922859 }923860 page_dirty--;861861+ count++;862862+ }863863+ } else if (buffer_uptodate(bh) && startio) {864864+ /*865865+ * we got here because the buffer is already mapped.866866+ * That means it must already have extents allocated867867+ * underneath it. Map the extent by reading it.868868+ */869869+ if (!iomap_valid || type != 0) {870870+ flags = BMAPI_READ;871871+ size = xfs_probe_cluster(inode, page, bh,872872+ head, 1);873873+ err = xfs_map_blocks(inode, offset, size,874874+ &iomap, flags);875875+ if (err)876876+ goto error;877877+ iomap_valid = xfs_iomap_valid(&iomap, offset);878878+ }879879+880880+ type = 0;881881+ if (!test_and_set_bit(BH_Lock, &bh->b_state)) {882882+ ASSERT(buffer_mapped(bh));883883+ if (iomap_valid)884884+ all_bh = 1;885885+ xfs_add_to_ioend(inode, bh, offset, type,886886+ &ioend, !iomap_valid);887887+ page_dirty--;888888+ count++;889889+ } else {890890+ iomap_valid = 0;924891 }925892 } else if ((buffer_uptodate(bh) || PageUptodate(page)) &&926893 (unmapped || startio)) {927927-928928- if (!buffer_mapped(bh)) {929929- int size;930930-931931- /*932932- * Getting here implies an unmapped buffer933933- * was found, and we are in a path where we934934- * need to write the whole page out.935935- */936936- if (!iomp) {937937- size = xfs_probe_unmapped_cluster(938938- inode, page, bh, head);939939- err = xfs_map_blocks(inode, offset,940940- size, &iomap,941941- BMAPI_WRITE|BMAPI_MMAP);942942- if (err) {943943- goto error;944944- }945945- iomp = xfs_offset_to_map(page, &iomap,946946- p_offset);947947- }948948- if (iomp) {949949- xfs_map_at_offset(page,950950- bh, p_offset,951951- inode->i_blkbits, iomp);952952- if (startio) {953953- bh_arr[cnt++] = bh;954954- } else {955955- set_buffer_dirty(bh);956956- unlock_buffer(bh);957957- mark_buffer_dirty(bh);958958- }959959- page_dirty--;960960- }961961- } else if (startio) {962962- if (buffer_uptodate(bh) &&963963- !test_and_set_bit(BH_Lock, &bh->b_state)) {964964- bh_arr[cnt++] = bh;965965- page_dirty--;966966- }967967- }894894+ iomap_valid = 0;968895 }969969- } while (offset += len, p_offset += len,970970- ((bh = bh->b_this_page) != head));896896+897897+ if (!iohead)898898+ iohead = ioend;899899+900900+ } while (offset += len, ((bh = bh->b_this_page) != head));971901972902 if (uptodate && bh == head)973903 SetPageUptodate(page);974904975975- if (startio) {976976- xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);977977- }905905+ if (startio)906906+ xfs_start_page_writeback(page, wbc, 1, count);978907979979- if (iomp) {980980- offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>908908+ if (ioend && iomap_valid) {909909+ offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >>981910 PAGE_CACHE_SHIFT;982911 tlast = min_t(pgoff_t, offset, last_index);983983- xfs_cluster_write(inode, page->index + 1, iomp, wbc,984984- startio, unmapped, tlast);912912+ xfs_cluster_write(inode, page->index + 1, &iomap, &ioend,913913+ wbc, startio, all_bh, tlast);985914 }915915+916916+ if (iohead)917917+ xfs_submit_ioend(iohead);986918987919 return page_dirty;988920989921error:990990- for (i = 0; i < cnt; i++) {991991- unlock_buffer(bh_arr[i]);992992- }922922+ if (iohead)923923+ xfs_cancel_ioend(iohead);993924994925 /*995926 * If it's delalloc and we have nowhere to put it,···1009916 * us to try again.1010917 */1011918 if (err != -EAGAIN) {10121012- if (!unmapped) {919919+ if (!unmapped)1013920 block_invalidatepage(page, 0);10141014- }1015921 ClearPageUptodate(page);1016922 }1017923 return err;···1074982 }10759831076984 /* If this is a realtime file, data might be on a new device */10771077- bh_result->b_bdev = iomap.iomap_target->pbr_bdev;985985+ bh_result->b_bdev = iomap.iomap_target->bt_bdev;10789861079987 /* If we previously allocated a block out beyond eof and1080988 * we are now coming back to use it then we will need to···11861094 if (error)11871095 return -error;1188109611891189- iocb->private = xfs_alloc_ioend(inode);10971097+ iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);1190109811911099 ret = blockdev_direct_IO_own_locking(rw, iocb, inode,11921192- iomap.iomap_target->pbr_bdev,11001100+ iomap.iomap_target->bt_bdev,11931101 iov, offset, nr_segs,11941102 linvfs_get_blocks_direct,11951103 linvfs_end_io_direct);
+10
fs/xfs/linux-2.6/xfs_aops.h
···23232424typedef void (*xfs_ioend_func_t)(void *);25252626+/*2727+ * xfs_ioend struct manages large extent writes for XFS.2828+ * It can manage several multi-page bio's at once.2929+ */2630typedef struct xfs_ioend {3131+ struct xfs_ioend *io_list; /* next ioend in chain */3232+ unsigned int io_type; /* delalloc / unwritten */2733 unsigned int io_uptodate; /* I/O status register */2834 atomic_t io_remaining; /* hold count */2935 struct vnode *io_vnode; /* file being written to */3036 struct buffer_head *io_buffer_head;/* buffer linked list head */3737+ struct buffer_head *io_buffer_tail;/* buffer linked list tail */3138 size_t io_size; /* size of the extent */3239 xfs_off_t io_offset; /* offset in the file */3340 struct work_struct io_work; /* xfsdatad work queue */3441} xfs_ioend_t;4242+4343+extern struct address_space_operations linvfs_aops;4444+extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);35453646#endif /* __XFS_IOPS_H__ */
+661-702
fs/xfs/linux-2.6/xfs_buf.c
···3131#include <linux/kthread.h>3232#include "xfs_linux.h"33333434-STATIC kmem_cache_t *pagebuf_zone;3535-STATIC kmem_shaker_t pagebuf_shake;3434+STATIC kmem_zone_t *xfs_buf_zone;3535+STATIC kmem_shaker_t xfs_buf_shake;3636+STATIC int xfsbufd(void *);3637STATIC int xfsbufd_wakeup(int, gfp_t);3737-STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);3838+STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int);38393940STATIC struct workqueue_struct *xfslogd_workqueue;4041struct workqueue_struct *xfsdatad_workqueue;41424242-#ifdef PAGEBUF_TRACE4343+#ifdef XFS_BUF_TRACE4344void4444-pagebuf_trace(4545- xfs_buf_t *pb,4545+xfs_buf_trace(4646+ xfs_buf_t *bp,4647 char *id,4748 void *data,4849 void *ra)4950{5050- ktrace_enter(pagebuf_trace_buf,5151- pb, id,5252- (void *)(unsigned long)pb->pb_flags,5353- (void *)(unsigned long)pb->pb_hold.counter,5454- (void *)(unsigned long)pb->pb_sema.count.counter,5151+ ktrace_enter(xfs_buf_trace_buf,5252+ bp, id,5353+ (void *)(unsigned long)bp->b_flags,5454+ (void *)(unsigned long)bp->b_hold.counter,5555+ (void *)(unsigned long)bp->b_sema.count.counter,5556 (void *)current,5657 data, ra,5757- (void *)(unsigned long)((pb->pb_file_offset>>32) & 0xffffffff),5858- (void *)(unsigned long)(pb->pb_file_offset & 0xffffffff),5959- (void *)(unsigned long)pb->pb_buffer_length,5858+ (void *)(unsigned long)((bp->b_file_offset>>32) & 0xffffffff),5959+ (void *)(unsigned long)(bp->b_file_offset & 0xffffffff),6060+ (void *)(unsigned long)bp->b_buffer_length,6061 NULL, NULL, NULL, NULL, NULL);6162}6262-ktrace_t *pagebuf_trace_buf;6363-#define PAGEBUF_TRACE_SIZE 40966464-#define PB_TRACE(pb, id, data) \6565- pagebuf_trace(pb, id, (void *)data, (void *)__builtin_return_address(0))6363+ktrace_t *xfs_buf_trace_buf;6464+#define XFS_BUF_TRACE_SIZE 40966565+#define XB_TRACE(bp, id, data) \6666+ xfs_buf_trace(bp, id, (void *)data, (void *)__builtin_return_address(0))6667#else6767-#define PB_TRACE(pb, id, data) do { } while (0)6868+#define XB_TRACE(bp, id, data) do { } while (0)6869#endif69707070-#ifdef PAGEBUF_LOCK_TRACKING7171-# define PB_SET_OWNER(pb) ((pb)->pb_last_holder = current->pid)7272-# define PB_CLEAR_OWNER(pb) ((pb)->pb_last_holder = -1)7373-# define PB_GET_OWNER(pb) ((pb)->pb_last_holder)7171+#ifdef XFS_BUF_LOCK_TRACKING7272+# define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid)7373+# define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1)7474+# define XB_GET_OWNER(bp) ((bp)->b_last_holder)7475#else7575-# define PB_SET_OWNER(pb) do { } while (0)7676-# define PB_CLEAR_OWNER(pb) do { } while (0)7777-# define PB_GET_OWNER(pb) do { } while (0)7676+# define XB_SET_OWNER(bp) do { } while (0)7777+# define XB_CLEAR_OWNER(bp) do { } while (0)7878+# define XB_GET_OWNER(bp) do { } while (0)7879#endif79808080-#define pb_to_gfp(flags) \8181- ((((flags) & PBF_READ_AHEAD) ? __GFP_NORETRY : \8282- ((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)8181+#define xb_to_gfp(flags) \8282+ ((((flags) & XBF_READ_AHEAD) ? __GFP_NORETRY : \8383+ ((flags) & XBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)83848484-#define pb_to_km(flags) \8585- (((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)8585+#define xb_to_km(flags) \8686+ (((flags) & XBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)86878787-#define pagebuf_allocate(flags) \8888- kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))8989-#define pagebuf_deallocate(pb) \9090- kmem_zone_free(pagebuf_zone, (pb));8888+#define xfs_buf_allocate(flags) \8989+ kmem_zone_alloc(xfs_buf_zone, xb_to_km(flags))9090+#define xfs_buf_deallocate(bp) \9191+ kmem_zone_free(xfs_buf_zone, (bp));91929293/*9393- * Page Region interfaces.9494+ * Page Region interfaces.9495 *9595- * For pages in filesystems where the blocksize is smaller than the9696- * pagesize, we use the page->private field (long) to hold a bitmap9797- * of uptodate regions within the page.9696+ * For pages in filesystems where the blocksize is smaller than the9797+ * pagesize, we use the page->private field (long) to hold a bitmap9898+ * of uptodate regions within the page.9899 *9999- * Each such region is "bytes per page / bits per long" bytes long.100100+ * Each such region is "bytes per page / bits per long" bytes long.100101 *101101- * NBPPR == number-of-bytes-per-page-region102102- * BTOPR == bytes-to-page-region (rounded up)103103- * BTOPRT == bytes-to-page-region-truncated (rounded down)102102+ * NBPPR == number-of-bytes-per-page-region103103+ * BTOPR == bytes-to-page-region (rounded up)104104+ * BTOPRT == bytes-to-page-region-truncated (rounded down)104105 */105106#if (BITS_PER_LONG == 32)106107#define PRSHIFT (PAGE_CACHE_SHIFT - 5) /* (32 == 1<<5) */···160159}161160162161/*163163- * Mapping of multi-page buffers into contiguous virtual space162162+ * Mapping of multi-page buffers into contiguous virtual space164163 */165164166165typedef struct a_list {···173172STATIC DEFINE_SPINLOCK(as_lock);174173175174/*176176- * Try to batch vunmaps because they are costly.175175+ * Try to batch vunmaps because they are costly.177176 */178177STATIC void179178free_address(···216215}217216218217/*219219- * Internal pagebuf object manipulation218218+ * Internal xfs_buf_t object manipulation220219 */221220222221STATIC void223223-_pagebuf_initialize(224224- xfs_buf_t *pb,222222+_xfs_buf_initialize(223223+ xfs_buf_t *bp,225224 xfs_buftarg_t *target,226226- loff_t range_base,225225+ xfs_off_t range_base,227226 size_t range_length,228228- page_buf_flags_t flags)227227+ xfs_buf_flags_t flags)229228{230229 /*231231- * We don't want certain flags to appear in pb->pb_flags.230230+ * We don't want certain flags to appear in b_flags.232231 */233233- flags &= ~(PBF_LOCK|PBF_MAPPED|PBF_DONT_BLOCK|PBF_READ_AHEAD);232232+ flags &= ~(XBF_LOCK|XBF_MAPPED|XBF_DONT_BLOCK|XBF_READ_AHEAD);234233235235- memset(pb, 0, sizeof(xfs_buf_t));236236- atomic_set(&pb->pb_hold, 1);237237- init_MUTEX_LOCKED(&pb->pb_iodonesema);238238- INIT_LIST_HEAD(&pb->pb_list);239239- INIT_LIST_HEAD(&pb->pb_hash_list);240240- init_MUTEX_LOCKED(&pb->pb_sema); /* held, no waiters */241241- PB_SET_OWNER(pb);242242- pb->pb_target = target;243243- pb->pb_file_offset = range_base;234234+ memset(bp, 0, sizeof(xfs_buf_t));235235+ atomic_set(&bp->b_hold, 1);236236+ init_MUTEX_LOCKED(&bp->b_iodonesema);237237+ INIT_LIST_HEAD(&bp->b_list);238238+ INIT_LIST_HEAD(&bp->b_hash_list);239239+ init_MUTEX_LOCKED(&bp->b_sema); /* held, no waiters */240240+ XB_SET_OWNER(bp);241241+ bp->b_target = target;242242+ bp->b_file_offset = range_base;244243 /*245244 * Set buffer_length and count_desired to the same value initially.246245 * I/O routines should use count_desired, which will be the same in247246 * most cases but may be reset (e.g. XFS recovery).248247 */249249- pb->pb_buffer_length = pb->pb_count_desired = range_length;250250- pb->pb_flags = flags;251251- pb->pb_bn = XFS_BUF_DADDR_NULL;252252- atomic_set(&pb->pb_pin_count, 0);253253- init_waitqueue_head(&pb->pb_waiters);248248+ bp->b_buffer_length = bp->b_count_desired = range_length;249249+ bp->b_flags = flags;250250+ bp->b_bn = XFS_BUF_DADDR_NULL;251251+ atomic_set(&bp->b_pin_count, 0);252252+ init_waitqueue_head(&bp->b_waiters);254253255255- XFS_STATS_INC(pb_create);256256- PB_TRACE(pb, "initialize", target);254254+ XFS_STATS_INC(xb_create);255255+ XB_TRACE(bp, "initialize", target);257256}258257259258/*260260- * Allocate a page array capable of holding a specified number261261- * of pages, and point the page buf at it.259259+ * Allocate a page array capable of holding a specified number260260+ * of pages, and point the page buf at it.262261 */263262STATIC int264264-_pagebuf_get_pages(265265- xfs_buf_t *pb,263263+_xfs_buf_get_pages(264264+ xfs_buf_t *bp,266265 int page_count,267267- page_buf_flags_t flags)266266+ xfs_buf_flags_t flags)268267{269268 /* Make sure that we have a page list */270270- if (pb->pb_pages == NULL) {271271- pb->pb_offset = page_buf_poff(pb->pb_file_offset);272272- pb->pb_page_count = page_count;273273- if (page_count <= PB_PAGES) {274274- pb->pb_pages = pb->pb_page_array;269269+ if (bp->b_pages == NULL) {270270+ bp->b_offset = xfs_buf_poff(bp->b_file_offset);271271+ bp->b_page_count = page_count;272272+ if (page_count <= XB_PAGES) {273273+ bp->b_pages = bp->b_page_array;275274 } else {276276- pb->pb_pages = kmem_alloc(sizeof(struct page *) *277277- page_count, pb_to_km(flags));278278- if (pb->pb_pages == NULL)275275+ bp->b_pages = kmem_alloc(sizeof(struct page *) *276276+ page_count, xb_to_km(flags));277277+ if (bp->b_pages == NULL)279278 return -ENOMEM;280279 }281281- memset(pb->pb_pages, 0, sizeof(struct page *) * page_count);280280+ memset(bp->b_pages, 0, sizeof(struct page *) * page_count);282281 }283282 return 0;284283}285284286285/*287287- * Frees pb_pages if it was malloced.286286+ * Frees b_pages if it was allocated.288287 */289288STATIC void290290-_pagebuf_free_pages(289289+_xfs_buf_free_pages(291290 xfs_buf_t *bp)292291{293293- if (bp->pb_pages != bp->pb_page_array) {294294- kmem_free(bp->pb_pages,295295- bp->pb_page_count * sizeof(struct page *));292292+ if (bp->b_pages != bp->b_page_array) {293293+ kmem_free(bp->b_pages,294294+ bp->b_page_count * sizeof(struct page *));296295 }297296}298297···300299 * Releases the specified buffer.301300 *302301 * The modification state of any associated pages is left unchanged.303303- * The buffer most not be on any hash - use pagebuf_rele instead for302302+ * The buffer most not be on any hash - use xfs_buf_rele instead for304303 * hashed and refcounted buffers305304 */306305void307307-pagebuf_free(306306+xfs_buf_free(308307 xfs_buf_t *bp)309308{310310- PB_TRACE(bp, "free", 0);309309+ XB_TRACE(bp, "free", 0);311310312312- ASSERT(list_empty(&bp->pb_hash_list));311311+ ASSERT(list_empty(&bp->b_hash_list));313312314314- if (bp->pb_flags & _PBF_PAGE_CACHE) {313313+ if (bp->b_flags & _XBF_PAGE_CACHE) {315314 uint i;316315317317- if ((bp->pb_flags & PBF_MAPPED) && (bp->pb_page_count > 1))318318- free_address(bp->pb_addr - bp->pb_offset);316316+ if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))317317+ free_address(bp->b_addr - bp->b_offset);319318320320- for (i = 0; i < bp->pb_page_count; i++)321321- page_cache_release(bp->pb_pages[i]);322322- _pagebuf_free_pages(bp);323323- } else if (bp->pb_flags & _PBF_KMEM_ALLOC) {319319+ for (i = 0; i < bp->b_page_count; i++)320320+ page_cache_release(bp->b_pages[i]);321321+ _xfs_buf_free_pages(bp);322322+ } else if (bp->b_flags & _XBF_KMEM_ALLOC) {324323 /*325325- * XXX(hch): bp->pb_count_desired might be incorrect (see326326- * pagebuf_associate_memory for details), but fortunately324324+ * XXX(hch): bp->b_count_desired might be incorrect (see325325+ * xfs_buf_associate_memory for details), but fortunately327326 * the Linux version of kmem_free ignores the len argument..328327 */329329- kmem_free(bp->pb_addr, bp->pb_count_desired);330330- _pagebuf_free_pages(bp);328328+ kmem_free(bp->b_addr, bp->b_count_desired);329329+ _xfs_buf_free_pages(bp);331330 }332331333333- pagebuf_deallocate(bp);332332+ xfs_buf_deallocate(bp);334333}335334336335/*337336 * Finds all pages for buffer in question and builds it's page list.338337 */339338STATIC int340340-_pagebuf_lookup_pages(339339+_xfs_buf_lookup_pages(341340 xfs_buf_t *bp,342341 uint flags)343342{344344- struct address_space *mapping = bp->pb_target->pbr_mapping;345345- size_t blocksize = bp->pb_target->pbr_bsize;346346- size_t size = bp->pb_count_desired;343343+ struct address_space *mapping = bp->b_target->bt_mapping;344344+ size_t blocksize = bp->b_target->bt_bsize;345345+ size_t size = bp->b_count_desired;347346 size_t nbytes, offset;348348- gfp_t gfp_mask = pb_to_gfp(flags);347347+ gfp_t gfp_mask = xb_to_gfp(flags);349348 unsigned short page_count, i;350349 pgoff_t first;351351- loff_t end;350350+ xfs_off_t end;352351 int error;353352354354- end = bp->pb_file_offset + bp->pb_buffer_length;355355- page_count = page_buf_btoc(end) - page_buf_btoct(bp->pb_file_offset);353353+ end = bp->b_file_offset + bp->b_buffer_length;354354+ page_count = xfs_buf_btoc(end) - xfs_buf_btoct(bp->b_file_offset);356355357357- error = _pagebuf_get_pages(bp, page_count, flags);356356+ error = _xfs_buf_get_pages(bp, page_count, flags);358357 if (unlikely(error))359358 return error;360360- bp->pb_flags |= _PBF_PAGE_CACHE;359359+ bp->b_flags |= _XBF_PAGE_CACHE;361360362362- offset = bp->pb_offset;363363- first = bp->pb_file_offset >> PAGE_CACHE_SHIFT;361361+ offset = bp->b_offset;362362+ first = bp->b_file_offset >> PAGE_CACHE_SHIFT;364363365365- for (i = 0; i < bp->pb_page_count; i++) {364364+ for (i = 0; i < bp->b_page_count; i++) {366365 struct page *page;367366 uint retries = 0;368367369368 retry:370369 page = find_or_create_page(mapping, first + i, gfp_mask);371370 if (unlikely(page == NULL)) {372372- if (flags & PBF_READ_AHEAD) {373373- bp->pb_page_count = i;374374- for (i = 0; i < bp->pb_page_count; i++)375375- unlock_page(bp->pb_pages[i]);371371+ if (flags & XBF_READ_AHEAD) {372372+ bp->b_page_count = i;373373+ for (i = 0; i < bp->b_page_count; i++)374374+ unlock_page(bp->b_pages[i]);376375 return -ENOMEM;377376 }378377···388387 "deadlock in %s (mode:0x%x)\n",389388 __FUNCTION__, gfp_mask);390389391391- XFS_STATS_INC(pb_page_retries);390390+ XFS_STATS_INC(xb_page_retries);392391 xfsbufd_wakeup(0, gfp_mask);393392 blk_congestion_wait(WRITE, HZ/50);394393 goto retry;395394 }396395397397- XFS_STATS_INC(pb_page_found);396396+ XFS_STATS_INC(xb_page_found);398397399398 nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset);400399 size -= nbytes;···402401 if (!PageUptodate(page)) {403402 page_count--;404403 if (blocksize >= PAGE_CACHE_SIZE) {405405- if (flags & PBF_READ)406406- bp->pb_locked = 1;404404+ if (flags & XBF_READ)405405+ bp->b_locked = 1;407406 } else if (!PagePrivate(page)) {408407 if (test_page_region(page, offset, nbytes))409408 page_count++;410409 }411410 }412411413413- bp->pb_pages[i] = page;412412+ bp->b_pages[i] = page;414413 offset = 0;415414 }416415417417- if (!bp->pb_locked) {418418- for (i = 0; i < bp->pb_page_count; i++)419419- unlock_page(bp->pb_pages[i]);416416+ if (!bp->b_locked) {417417+ for (i = 0; i < bp->b_page_count; i++)418418+ unlock_page(bp->b_pages[i]);420419 }421420422422- if (page_count == bp->pb_page_count)423423- bp->pb_flags |= PBF_DONE;421421+ if (page_count == bp->b_page_count)422422+ bp->b_flags |= XBF_DONE;424423425425- PB_TRACE(bp, "lookup_pages", (long)page_count);424424+ XB_TRACE(bp, "lookup_pages", (long)page_count);426425 return error;427426}428427···430429 * Map buffer into kernel address-space if nessecary.431430 */432431STATIC int433433-_pagebuf_map_pages(432432+_xfs_buf_map_pages(434433 xfs_buf_t *bp,435434 uint flags)436435{437436 /* A single page buffer is always mappable */438438- if (bp->pb_page_count == 1) {439439- bp->pb_addr = page_address(bp->pb_pages[0]) + bp->pb_offset;440440- bp->pb_flags |= PBF_MAPPED;441441- } else if (flags & PBF_MAPPED) {437437+ if (bp->b_page_count == 1) {438438+ bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset;439439+ bp->b_flags |= XBF_MAPPED;440440+ } else if (flags & XBF_MAPPED) {442441 if (as_list_len > 64)443442 purge_addresses();444444- bp->pb_addr = vmap(bp->pb_pages, bp->pb_page_count,445445- VM_MAP, PAGE_KERNEL);446446- if (unlikely(bp->pb_addr == NULL))443443+ bp->b_addr = vmap(bp->b_pages, bp->b_page_count,444444+ VM_MAP, PAGE_KERNEL);445445+ if (unlikely(bp->b_addr == NULL))447446 return -ENOMEM;448448- bp->pb_addr += bp->pb_offset;449449- bp->pb_flags |= PBF_MAPPED;447447+ bp->b_addr += bp->b_offset;448448+ bp->b_flags |= XBF_MAPPED;450449 }451450452451 return 0;···457456 */458457459458/*460460- * _pagebuf_find461461- *462462- * Looks up, and creates if absent, a lockable buffer for459459+ * Look up, and creates if absent, a lockable buffer for463460 * a given range of an inode. The buffer is returned464461 * locked. If other overlapping buffers exist, they are465462 * released before the new buffer is created and locked,···465466 * are unlocked. No I/O is implied by this call.466467 */467468xfs_buf_t *468468-_pagebuf_find(469469+_xfs_buf_find(469470 xfs_buftarg_t *btp, /* block device target */470470- loff_t ioff, /* starting offset of range */471471+ xfs_off_t ioff, /* starting offset of range */471472 size_t isize, /* length of range */472472- page_buf_flags_t flags, /* PBF_TRYLOCK */473473- xfs_buf_t *new_pb)/* newly allocated buffer */473473+ xfs_buf_flags_t flags,474474+ xfs_buf_t *new_bp)474475{475475- loff_t range_base;476476+ xfs_off_t range_base;476477 size_t range_length;477478 xfs_bufhash_t *hash;478478- xfs_buf_t *pb, *n;479479+ xfs_buf_t *bp, *n;479480480481 range_base = (ioff << BBSHIFT);481482 range_length = (isize << BBSHIFT);482483483484 /* Check for IOs smaller than the sector size / not sector aligned */484484- ASSERT(!(range_length < (1 << btp->pbr_sshift)));485485- ASSERT(!(range_base & (loff_t)btp->pbr_smask));485485+ ASSERT(!(range_length < (1 << btp->bt_sshift)));486486+ ASSERT(!(range_base & (xfs_off_t)btp->bt_smask));486487487488 hash = &btp->bt_hash[hash_long((unsigned long)ioff, btp->bt_hashshift)];488489489490 spin_lock(&hash->bh_lock);490491491491- list_for_each_entry_safe(pb, n, &hash->bh_list, pb_hash_list) {492492- ASSERT(btp == pb->pb_target);493493- if (pb->pb_file_offset == range_base &&494494- pb->pb_buffer_length == range_length) {492492+ list_for_each_entry_safe(bp, n, &hash->bh_list, b_hash_list) {493493+ ASSERT(btp == bp->b_target);494494+ if (bp->b_file_offset == range_base &&495495+ bp->b_buffer_length == range_length) {495496 /*496496- * If we look at something bring it to the497497+ * If we look at something, bring it to the497498 * front of the list for next time.498499 */499499- atomic_inc(&pb->pb_hold);500500- list_move(&pb->pb_hash_list, &hash->bh_list);500500+ atomic_inc(&bp->b_hold);501501+ list_move(&bp->b_hash_list, &hash->bh_list);501502 goto found;502503 }503504 }504505505506 /* No match found */506506- if (new_pb) {507507- _pagebuf_initialize(new_pb, btp, range_base,507507+ if (new_bp) {508508+ _xfs_buf_initialize(new_bp, btp, range_base,508509 range_length, flags);509509- new_pb->pb_hash = hash;510510- list_add(&new_pb->pb_hash_list, &hash->bh_list);510510+ new_bp->b_hash = hash;511511+ list_add(&new_bp->b_hash_list, &hash->bh_list);511512 } else {512512- XFS_STATS_INC(pb_miss_locked);513513+ XFS_STATS_INC(xb_miss_locked);513514 }514515515516 spin_unlock(&hash->bh_lock);516516- return new_pb;517517+ return new_bp;517518518519found:519520 spin_unlock(&hash->bh_lock);···522523 * if this does not work then we need to drop the523524 * spinlock and do a hard attempt on the semaphore.524525 */525525- if (down_trylock(&pb->pb_sema)) {526526- if (!(flags & PBF_TRYLOCK)) {526526+ if (down_trylock(&bp->b_sema)) {527527+ if (!(flags & XBF_TRYLOCK)) {527528 /* wait for buffer ownership */528528- PB_TRACE(pb, "get_lock", 0);529529- pagebuf_lock(pb);530530- XFS_STATS_INC(pb_get_locked_waited);529529+ XB_TRACE(bp, "get_lock", 0);530530+ xfs_buf_lock(bp);531531+ XFS_STATS_INC(xb_get_locked_waited);531532 } else {532533 /* We asked for a trylock and failed, no need533534 * to look at file offset and length here, we534534- * know that this pagebuf at least overlaps our535535- * pagebuf and is locked, therefore our buffer536536- * either does not exist, or is this buffer535535+ * know that this buffer at least overlaps our536536+ * buffer and is locked, therefore our buffer537537+ * either does not exist, or is this buffer.537538 */538538-539539- pagebuf_rele(pb);540540- XFS_STATS_INC(pb_busy_locked);541541- return (NULL);539539+ xfs_buf_rele(bp);540540+ XFS_STATS_INC(xb_busy_locked);541541+ return NULL;542542 }543543 } else {544544 /* trylock worked */545545- PB_SET_OWNER(pb);545545+ XB_SET_OWNER(bp);546546 }547547548548- if (pb->pb_flags & PBF_STALE) {549549- ASSERT((pb->pb_flags & _PBF_DELWRI_Q) == 0);550550- pb->pb_flags &= PBF_MAPPED;548548+ if (bp->b_flags & XBF_STALE) {549549+ ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);550550+ bp->b_flags &= XBF_MAPPED;551551 }552552- PB_TRACE(pb, "got_lock", 0);553553- XFS_STATS_INC(pb_get_locked);554554- return (pb);552552+ XB_TRACE(bp, "got_lock", 0);553553+ XFS_STATS_INC(xb_get_locked);554554+ return bp;555555}556556557557/*558558- * xfs_buf_get_flags assembles a buffer covering the specified range.559559- *558558+ * Assembles a buffer covering the specified range.560559 * Storage in memory for all portions of the buffer will be allocated,561560 * although backing storage may not be.562561 */563562xfs_buf_t *564564-xfs_buf_get_flags( /* allocate a buffer */563563+xfs_buf_get_flags(565564 xfs_buftarg_t *target,/* target for buffer */566566- loff_t ioff, /* starting offset of range */565565+ xfs_off_t ioff, /* starting offset of range */567566 size_t isize, /* length of range */568568- page_buf_flags_t flags) /* PBF_TRYLOCK */567567+ xfs_buf_flags_t flags)569568{570570- xfs_buf_t *pb, *new_pb;569569+ xfs_buf_t *bp, *new_bp;571570 int error = 0, i;572571573573- new_pb = pagebuf_allocate(flags);574574- if (unlikely(!new_pb))572572+ new_bp = xfs_buf_allocate(flags);573573+ if (unlikely(!new_bp))575574 return NULL;576575577577- pb = _pagebuf_find(target, ioff, isize, flags, new_pb);578578- if (pb == new_pb) {579579- error = _pagebuf_lookup_pages(pb, flags);576576+ bp = _xfs_buf_find(target, ioff, isize, flags, new_bp);577577+ if (bp == new_bp) {578578+ error = _xfs_buf_lookup_pages(bp, flags);580579 if (error)581580 goto no_buffer;582581 } else {583583- pagebuf_deallocate(new_pb);584584- if (unlikely(pb == NULL))582582+ xfs_buf_deallocate(new_bp);583583+ if (unlikely(bp == NULL))585584 return NULL;586585 }587586588588- for (i = 0; i < pb->pb_page_count; i++)589589- mark_page_accessed(pb->pb_pages[i]);587587+ for (i = 0; i < bp->b_page_count; i++)588588+ mark_page_accessed(bp->b_pages[i]);590589591591- if (!(pb->pb_flags & PBF_MAPPED)) {592592- error = _pagebuf_map_pages(pb, flags);590590+ if (!(bp->b_flags & XBF_MAPPED)) {591591+ error = _xfs_buf_map_pages(bp, flags);593592 if (unlikely(error)) {594593 printk(KERN_WARNING "%s: failed to map pages\n",595594 __FUNCTION__);···595598 }596599 }597600598598- XFS_STATS_INC(pb_get);601601+ XFS_STATS_INC(xb_get);599602600603 /*601604 * Always fill in the block number now, the mapped cases can do602605 * their own overlay of this later.603606 */604604- pb->pb_bn = ioff;605605- pb->pb_count_desired = pb->pb_buffer_length;607607+ bp->b_bn = ioff;608608+ bp->b_count_desired = bp->b_buffer_length;606609607607- PB_TRACE(pb, "get", (unsigned long)flags);608608- return pb;610610+ XB_TRACE(bp, "get", (unsigned long)flags);611611+ return bp;609612610613 no_buffer:611611- if (flags & (PBF_LOCK | PBF_TRYLOCK))612612- pagebuf_unlock(pb);613613- pagebuf_rele(pb);614614+ if (flags & (XBF_LOCK | XBF_TRYLOCK))615615+ xfs_buf_unlock(bp);616616+ xfs_buf_rele(bp);614617 return NULL;615618}616619617620xfs_buf_t *618621xfs_buf_read_flags(619622 xfs_buftarg_t *target,620620- loff_t ioff,623623+ xfs_off_t ioff,621624 size_t isize,622622- page_buf_flags_t flags)625625+ xfs_buf_flags_t flags)623626{624624- xfs_buf_t *pb;627627+ xfs_buf_t *bp;625628626626- flags |= PBF_READ;629629+ flags |= XBF_READ;627630628628- pb = xfs_buf_get_flags(target, ioff, isize, flags);629629- if (pb) {630630- if (!XFS_BUF_ISDONE(pb)) {631631- PB_TRACE(pb, "read", (unsigned long)flags);632632- XFS_STATS_INC(pb_get_read);633633- pagebuf_iostart(pb, flags);634634- } else if (flags & PBF_ASYNC) {635635- PB_TRACE(pb, "read_async", (unsigned long)flags);631631+ bp = xfs_buf_get_flags(target, ioff, isize, flags);632632+ if (bp) {633633+ if (!XFS_BUF_ISDONE(bp)) {634634+ XB_TRACE(bp, "read", (unsigned long)flags);635635+ XFS_STATS_INC(xb_get_read);636636+ xfs_buf_iostart(bp, flags);637637+ } else if (flags & XBF_ASYNC) {638638+ XB_TRACE(bp, "read_async", (unsigned long)flags);636639 /*637640 * Read ahead call which is already satisfied,638641 * drop the buffer639642 */640643 goto no_buffer;641644 } else {642642- PB_TRACE(pb, "read_done", (unsigned long)flags);645645+ XB_TRACE(bp, "read_done", (unsigned long)flags);643646 /* We do not want read in the flags */644644- pb->pb_flags &= ~PBF_READ;647647+ bp->b_flags &= ~XBF_READ;645648 }646649 }647650648648- return pb;651651+ return bp;649652650653 no_buffer:651651- if (flags & (PBF_LOCK | PBF_TRYLOCK))652652- pagebuf_unlock(pb);653653- pagebuf_rele(pb);654654+ if (flags & (XBF_LOCK | XBF_TRYLOCK))655655+ xfs_buf_unlock(bp);656656+ xfs_buf_rele(bp);654657 return NULL;655658}656659657660/*658658- * If we are not low on memory then do the readahead in a deadlock659659- * safe manner.661661+ * If we are not low on memory then do the readahead in a deadlock662662+ * safe manner.660663 */661664void662662-pagebuf_readahead(665665+xfs_buf_readahead(663666 xfs_buftarg_t *target,664664- loff_t ioff,667667+ xfs_off_t ioff,665668 size_t isize,666666- page_buf_flags_t flags)669669+ xfs_buf_flags_t flags)667670{668671 struct backing_dev_info *bdi;669672670670- bdi = target->pbr_mapping->backing_dev_info;673673+ bdi = target->bt_mapping->backing_dev_info;671674 if (bdi_read_congested(bdi))672675 return;673676674674- flags |= (PBF_TRYLOCK|PBF_ASYNC|PBF_READ_AHEAD);677677+ flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD);675678 xfs_buf_read_flags(target, ioff, isize, flags);676679}677680678681xfs_buf_t *679679-pagebuf_get_empty(682682+xfs_buf_get_empty(680683 size_t len,681684 xfs_buftarg_t *target)682685{683683- xfs_buf_t *pb;686686+ xfs_buf_t *bp;684687685685- pb = pagebuf_allocate(0);686686- if (pb)687687- _pagebuf_initialize(pb, target, 0, len, 0);688688- return pb;688688+ bp = xfs_buf_allocate(0);689689+ if (bp)690690+ _xfs_buf_initialize(bp, target, 0, len, 0);691691+ return bp;689692}690693691694static inline struct page *···701704}702705703706int704704-pagebuf_associate_memory(705705- xfs_buf_t *pb,707707+xfs_buf_associate_memory(708708+ xfs_buf_t *bp,706709 void *mem,707710 size_t len)708711{···719722 page_count++;720723721724 /* Free any previous set of page pointers */722722- if (pb->pb_pages)723723- _pagebuf_free_pages(pb);725725+ if (bp->b_pages)726726+ _xfs_buf_free_pages(bp);724727725725- pb->pb_pages = NULL;726726- pb->pb_addr = mem;728728+ bp->b_pages = NULL;729729+ bp->b_addr = mem;727730728728- rval = _pagebuf_get_pages(pb, page_count, 0);731731+ rval = _xfs_buf_get_pages(bp, page_count, 0);729732 if (rval)730733 return rval;731734732732- pb->pb_offset = offset;735735+ bp->b_offset = offset;733736 ptr = (size_t) mem & PAGE_CACHE_MASK;734737 end = PAGE_CACHE_ALIGN((size_t) mem + len);735738 end_cur = end;736739 /* set up first page */737737- pb->pb_pages[0] = mem_to_page(mem);740740+ bp->b_pages[0] = mem_to_page(mem);738741739742 ptr += PAGE_CACHE_SIZE;740740- pb->pb_page_count = ++i;743743+ bp->b_page_count = ++i;741744 while (ptr < end) {742742- pb->pb_pages[i] = mem_to_page((void *)ptr);743743- pb->pb_page_count = ++i;745745+ bp->b_pages[i] = mem_to_page((void *)ptr);746746+ bp->b_page_count = ++i;744747 ptr += PAGE_CACHE_SIZE;745748 }746746- pb->pb_locked = 0;749749+ bp->b_locked = 0;747750748748- pb->pb_count_desired = pb->pb_buffer_length = len;749749- pb->pb_flags |= PBF_MAPPED;751751+ bp->b_count_desired = bp->b_buffer_length = len;752752+ bp->b_flags |= XBF_MAPPED;750753751754 return 0;752755}753756754757xfs_buf_t *755755-pagebuf_get_no_daddr(758758+xfs_buf_get_noaddr(756759 size_t len,757760 xfs_buftarg_t *target)758761{···761764 void *data;762765 int error;763766764764- bp = pagebuf_allocate(0);767767+ bp = xfs_buf_allocate(0);765768 if (unlikely(bp == NULL))766769 goto fail;767767- _pagebuf_initialize(bp, target, 0, len, 0);770770+ _xfs_buf_initialize(bp, target, 0, len, 0);768771769772 try_again:770773 data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);···773776774777 /* check whether alignment matches.. */775778 if ((__psunsigned_t)data !=776776- ((__psunsigned_t)data & ~target->pbr_smask)) {779779+ ((__psunsigned_t)data & ~target->bt_smask)) {777780 /* .. else double the size and try again */778781 kmem_free(data, malloc_len);779782 malloc_len <<= 1;780783 goto try_again;781784 }782785783783- error = pagebuf_associate_memory(bp, data, len);786786+ error = xfs_buf_associate_memory(bp, data, len);784787 if (error)785788 goto fail_free_mem;786786- bp->pb_flags |= _PBF_KMEM_ALLOC;789789+ bp->b_flags |= _XBF_KMEM_ALLOC;787790788788- pagebuf_unlock(bp);791791+ xfs_buf_unlock(bp);789792790790- PB_TRACE(bp, "no_daddr", data);793793+ XB_TRACE(bp, "no_daddr", data);791794 return bp;792795 fail_free_mem:793796 kmem_free(data, malloc_len);794797 fail_free_buf:795795- pagebuf_free(bp);798798+ xfs_buf_free(bp);796799 fail:797800 return NULL;798801}799802800803/*801801- * pagebuf_hold802802- *803804 * Increment reference count on buffer, to hold the buffer concurrently804805 * with another thread which may release (free) the buffer asynchronously.805805- *806806 * Must hold the buffer already to call this function.807807 */808808void809809-pagebuf_hold(810810- xfs_buf_t *pb)809809+xfs_buf_hold(810810+ xfs_buf_t *bp)811811{812812- atomic_inc(&pb->pb_hold);813813- PB_TRACE(pb, "hold", 0);812812+ atomic_inc(&bp->b_hold);813813+ XB_TRACE(bp, "hold", 0);814814}815815816816/*817817- * pagebuf_rele818818- *819819- * pagebuf_rele releases a hold on the specified buffer. If the820820- * the hold count is 1, pagebuf_rele calls pagebuf_free.817817+ * Releases a hold on the specified buffer. If the818818+ * the hold count is 1, calls xfs_buf_free.821819 */822820void823823-pagebuf_rele(824824- xfs_buf_t *pb)821821+xfs_buf_rele(822822+ xfs_buf_t *bp)825823{826826- xfs_bufhash_t *hash = pb->pb_hash;824824+ xfs_bufhash_t *hash = bp->b_hash;827825828828- PB_TRACE(pb, "rele", pb->pb_relse);826826+ XB_TRACE(bp, "rele", bp->b_relse);829827830830- if (atomic_dec_and_lock(&pb->pb_hold, &hash->bh_lock)) {831831- if (pb->pb_relse) {832832- atomic_inc(&pb->pb_hold);828828+ if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) {829829+ if (bp->b_relse) {830830+ atomic_inc(&bp->b_hold);833831 spin_unlock(&hash->bh_lock);834834- (*(pb->pb_relse)) (pb);835835- } else if (pb->pb_flags & PBF_FS_MANAGED) {832832+ (*(bp->b_relse)) (bp);833833+ } else if (bp->b_flags & XBF_FS_MANAGED) {836834 spin_unlock(&hash->bh_lock);837835 } else {838838- ASSERT(!(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)));839839- list_del_init(&pb->pb_hash_list);836836+ ASSERT(!(bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)));837837+ list_del_init(&bp->b_hash_list);840838 spin_unlock(&hash->bh_lock);841841- pagebuf_free(pb);839839+ xfs_buf_free(bp);842840 }843841 } else {844842 /*845843 * Catch reference count leaks846844 */847847- ASSERT(atomic_read(&pb->pb_hold) >= 0);845845+ ASSERT(atomic_read(&bp->b_hold) >= 0);848846 }849847}850848···855863 */856864857865/*858858- * pagebuf_cond_lock859859- *860860- * pagebuf_cond_lock locks a buffer object, if it is not already locked.861861- * Note that this in no way862862- * locks the underlying pages, so it is only useful for synchronizing863863- * concurrent use of page buffer objects, not for synchronizing independent864864- * access to the underlying pages.866866+ * Locks a buffer object, if it is not already locked.867867+ * Note that this in no way locks the underlying pages, so it is only868868+ * useful for synchronizing concurrent use of buffer objects, not for869869+ * synchronizing independent access to the underlying pages.865870 */866871int867867-pagebuf_cond_lock( /* lock buffer, if not locked */868868- /* returns -EBUSY if locked) */869869- xfs_buf_t *pb)872872+xfs_buf_cond_lock(873873+ xfs_buf_t *bp)870874{871875 int locked;872876873873- locked = down_trylock(&pb->pb_sema) == 0;877877+ locked = down_trylock(&bp->b_sema) == 0;874878 if (locked) {875875- PB_SET_OWNER(pb);879879+ XB_SET_OWNER(bp);876880 }877877- PB_TRACE(pb, "cond_lock", (long)locked);878878- return(locked ? 0 : -EBUSY);881881+ XB_TRACE(bp, "cond_lock", (long)locked);882882+ return locked ? 0 : -EBUSY;879883}880884881885#if defined(DEBUG) || defined(XFS_BLI_TRACE)882882-/*883883- * pagebuf_lock_value884884- *885885- * Return lock value for a pagebuf886886- */887886int888888-pagebuf_lock_value(889889- xfs_buf_t *pb)887887+xfs_buf_lock_value(888888+ xfs_buf_t *bp)890889{891891- return(atomic_read(&pb->pb_sema.count));890890+ return atomic_read(&bp->b_sema.count);892891}893892#endif894893895894/*896896- * pagebuf_lock897897- *898898- * pagebuf_lock locks a buffer object. Note that this in no way899899- * locks the underlying pages, so it is only useful for synchronizing900900- * concurrent use of page buffer objects, not for synchronizing independent901901- * access to the underlying pages.895895+ * Locks a buffer object.896896+ * Note that this in no way locks the underlying pages, so it is only897897+ * useful for synchronizing concurrent use of buffer objects, not for898898+ * synchronizing independent access to the underlying pages.902899 */903903-int904904-pagebuf_lock(905905- xfs_buf_t *pb)900900+void901901+xfs_buf_lock(902902+ xfs_buf_t *bp)906903{907907- PB_TRACE(pb, "lock", 0);908908- if (atomic_read(&pb->pb_io_remaining))909909- blk_run_address_space(pb->pb_target->pbr_mapping);910910- down(&pb->pb_sema);911911- PB_SET_OWNER(pb);912912- PB_TRACE(pb, "locked", 0);913913- return 0;904904+ XB_TRACE(bp, "lock", 0);905905+ if (atomic_read(&bp->b_io_remaining))906906+ blk_run_address_space(bp->b_target->bt_mapping);907907+ down(&bp->b_sema);908908+ XB_SET_OWNER(bp);909909+ XB_TRACE(bp, "locked", 0);914910}915911916912/*917917- * pagebuf_unlock918918- *919919- * pagebuf_unlock releases the lock on the buffer object created by920920- * pagebuf_lock or pagebuf_cond_lock (not any pinning of underlying pages921921- * created by pagebuf_pin).922922- *913913+ * Releases the lock on the buffer object.923914 * If the buffer is marked delwri but is not queued, do so before we924924- * unlock the buffer as we need to set flags correctly. We also need to915915+ * unlock the buffer as we need to set flags correctly. We also need to925916 * take a reference for the delwri queue because the unlocker is going to926917 * drop their's and they don't know we just queued it.927918 */928919void929929-pagebuf_unlock( /* unlock buffer */930930- xfs_buf_t *pb) /* buffer to unlock */920920+xfs_buf_unlock(921921+ xfs_buf_t *bp)931922{932932- if ((pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)) == PBF_DELWRI) {933933- atomic_inc(&pb->pb_hold);934934- pb->pb_flags |= PBF_ASYNC;935935- pagebuf_delwri_queue(pb, 0);923923+ if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) {924924+ atomic_inc(&bp->b_hold);925925+ bp->b_flags |= XBF_ASYNC;926926+ xfs_buf_delwri_queue(bp, 0);936927 }937928938938- PB_CLEAR_OWNER(pb);939939- up(&pb->pb_sema);940940- PB_TRACE(pb, "unlock", 0);929929+ XB_CLEAR_OWNER(bp);930930+ up(&bp->b_sema);931931+ XB_TRACE(bp, "unlock", 0);941932}942933943934944935/*945936 * Pinning Buffer Storage in Memory946946- */947947-948948-/*949949- * pagebuf_pin950950- *951951- * pagebuf_pin locks all of the memory represented by a buffer in952952- * memory. Multiple calls to pagebuf_pin and pagebuf_unpin, for953953- * the same or different buffers affecting a given page, will954954- * properly count the number of outstanding "pin" requests. The955955- * buffer may be released after the pagebuf_pin and a different956956- * buffer used when calling pagebuf_unpin, if desired.957957- * pagebuf_pin should be used by the file system when it wants be958958- * assured that no attempt will be made to force the affected959959- * memory to disk. It does not assure that a given logical page960960- * will not be moved to a different physical page.937937+ * Ensure that no attempt to force a buffer to disk will succeed.961938 */962939void963963-pagebuf_pin(964964- xfs_buf_t *pb)940940+xfs_buf_pin(941941+ xfs_buf_t *bp)965942{966966- atomic_inc(&pb->pb_pin_count);967967- PB_TRACE(pb, "pin", (long)pb->pb_pin_count.counter);943943+ atomic_inc(&bp->b_pin_count);944944+ XB_TRACE(bp, "pin", (long)bp->b_pin_count.counter);968945}969946970970-/*971971- * pagebuf_unpin972972- *973973- * pagebuf_unpin reverses the locking of memory performed by974974- * pagebuf_pin. Note that both functions affected the logical975975- * pages associated with the buffer, not the buffer itself.976976- */977947void978978-pagebuf_unpin(979979- xfs_buf_t *pb)948948+xfs_buf_unpin(949949+ xfs_buf_t *bp)980950{981981- if (atomic_dec_and_test(&pb->pb_pin_count)) {982982- wake_up_all(&pb->pb_waiters);983983- }984984- PB_TRACE(pb, "unpin", (long)pb->pb_pin_count.counter);951951+ if (atomic_dec_and_test(&bp->b_pin_count))952952+ wake_up_all(&bp->b_waiters);953953+ XB_TRACE(bp, "unpin", (long)bp->b_pin_count.counter);985954}986955987956int988988-pagebuf_ispin(989989- xfs_buf_t *pb)957957+xfs_buf_ispin(958958+ xfs_buf_t *bp)990959{991991- return atomic_read(&pb->pb_pin_count);960960+ return atomic_read(&bp->b_pin_count);992961}993962994994-/*995995- * pagebuf_wait_unpin996996- *997997- * pagebuf_wait_unpin waits until all of the memory associated998998- * with the buffer is not longer locked in memory. It returns999999- * immediately if none of the affected pages are locked.10001000- */10011001-static inline void10021002-_pagebuf_wait_unpin(10031003- xfs_buf_t *pb)963963+STATIC void964964+xfs_buf_wait_unpin(965965+ xfs_buf_t *bp)1004966{1005967 DECLARE_WAITQUEUE (wait, current);100696810071007- if (atomic_read(&pb->pb_pin_count) == 0)969969+ if (atomic_read(&bp->b_pin_count) == 0)1008970 return;100997110101010- add_wait_queue(&pb->pb_waiters, &wait);972972+ add_wait_queue(&bp->b_waiters, &wait);1011973 for (;;) {1012974 set_current_state(TASK_UNINTERRUPTIBLE);10131013- if (atomic_read(&pb->pb_pin_count) == 0)975975+ if (atomic_read(&bp->b_pin_count) == 0)1014976 break;10151015- if (atomic_read(&pb->pb_io_remaining))10161016- blk_run_address_space(pb->pb_target->pbr_mapping);977977+ if (atomic_read(&bp->b_io_remaining))978978+ blk_run_address_space(bp->b_target->bt_mapping);1017979 schedule();1018980 }10191019- remove_wait_queue(&pb->pb_waiters, &wait);981981+ remove_wait_queue(&bp->b_waiters, &wait);1020982 set_current_state(TASK_RUNNING);1021983}1022984···9781032 * Buffer Utility Routines9791033 */9801034981981-/*982982- * pagebuf_iodone983983- *984984- * pagebuf_iodone marks a buffer for which I/O is in progress985985- * done with respect to that I/O. The pb_iodone routine, if986986- * present, will be called as a side-effect.987987- */9881035STATIC void989989-pagebuf_iodone_work(10361036+xfs_buf_iodone_work(9901037 void *v)9911038{9921039 xfs_buf_t *bp = (xfs_buf_t *)v;9931040994994- if (bp->pb_iodone)995995- (*(bp->pb_iodone))(bp);996996- else if (bp->pb_flags & PBF_ASYNC)10411041+ if (bp->b_iodone)10421042+ (*(bp->b_iodone))(bp);10431043+ else if (bp->b_flags & XBF_ASYNC)9971044 xfs_buf_relse(bp);9981045}999104610001047void10011001-pagebuf_iodone(10021002- xfs_buf_t *pb,10481048+xfs_buf_ioend(10491049+ xfs_buf_t *bp,10031050 int schedule)10041051{10051005- pb->pb_flags &= ~(PBF_READ | PBF_WRITE);10061006- if (pb->pb_error == 0)10071007- pb->pb_flags |= PBF_DONE;10521052+ bp->b_flags &= ~(XBF_READ | XBF_WRITE);10531053+ if (bp->b_error == 0)10541054+ bp->b_flags |= XBF_DONE;1008105510091009- PB_TRACE(pb, "iodone", pb->pb_iodone);10561056+ XB_TRACE(bp, "iodone", bp->b_iodone);1010105710111011- if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {10581058+ if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) {10121059 if (schedule) {10131013- INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);10141014- queue_work(xfslogd_workqueue, &pb->pb_iodone_work);10601060+ INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp);10611061+ queue_work(xfslogd_workqueue, &bp->b_iodone_work);10151062 } else {10161016- pagebuf_iodone_work(pb);10631063+ xfs_buf_iodone_work(bp);10171064 }10181065 } else {10191019- up(&pb->pb_iodonesema);10661066+ up(&bp->b_iodonesema);10201067 }10211068}1022106910231023-/*10241024- * pagebuf_ioerror10251025- *10261026- * pagebuf_ioerror sets the error code for a buffer.10271027- */10281070void10291029-pagebuf_ioerror( /* mark/clear buffer error flag */10301030- xfs_buf_t *pb, /* buffer to mark */10311031- int error) /* error to store (0 if none) */10711071+xfs_buf_ioerror(10721072+ xfs_buf_t *bp,10731073+ int error)10321074{10331075 ASSERT(error >= 0 && error <= 0xffff);10341034- pb->pb_error = (unsigned short)error;10351035- PB_TRACE(pb, "ioerror", (unsigned long)error);10761076+ bp->b_error = (unsigned short)error;10771077+ XB_TRACE(bp, "ioerror", (unsigned long)error);10361078}1037107910381080/*10391039- * pagebuf_iostart10401040- *10411041- * pagebuf_iostart initiates I/O on a buffer, based on the flags supplied.10421042- * If necessary, it will arrange for any disk space allocation required,10431043- * and it will break up the request if the block mappings require it.10441044- * The pb_iodone routine in the buffer supplied will only be called10811081+ * Initiate I/O on a buffer, based on the flags supplied.10821082+ * The b_iodone routine in the buffer supplied will only be called10451083 * when all of the subsidiary I/O requests, if any, have been completed.10461046- * pagebuf_iostart calls the pagebuf_ioinitiate routine or10471047- * pagebuf_iorequest, if the former routine is not defined, to start10481048- * the I/O on a given low-level request.10491084 */10501085int10511051-pagebuf_iostart( /* start I/O on a buffer */10521052- xfs_buf_t *pb, /* buffer to start */10531053- page_buf_flags_t flags) /* PBF_LOCK, PBF_ASYNC, PBF_READ, */10541054- /* PBF_WRITE, PBF_DELWRI, */10551055- /* PBF_DONT_BLOCK */10861086+xfs_buf_iostart(10871087+ xfs_buf_t *bp,10881088+ xfs_buf_flags_t flags)10561089{10571090 int status = 0;1058109110591059- PB_TRACE(pb, "iostart", (unsigned long)flags);10921092+ XB_TRACE(bp, "iostart", (unsigned long)flags);1060109310611061- if (flags & PBF_DELWRI) {10621062- pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC);10631063- pb->pb_flags |= flags & (PBF_DELWRI | PBF_ASYNC);10641064- pagebuf_delwri_queue(pb, 1);10941094+ if (flags & XBF_DELWRI) {10951095+ bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_ASYNC);10961096+ bp->b_flags |= flags & (XBF_DELWRI | XBF_ASYNC);10971097+ xfs_buf_delwri_queue(bp, 1);10651098 return status;10661099 }1067110010681068- pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | PBF_DELWRI | \10691069- PBF_READ_AHEAD | _PBF_RUN_QUEUES);10701070- pb->pb_flags |= flags & (PBF_READ | PBF_WRITE | PBF_ASYNC | \10711071- PBF_READ_AHEAD | _PBF_RUN_QUEUES);11011101+ bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_ASYNC | XBF_DELWRI | \11021102+ XBF_READ_AHEAD | _XBF_RUN_QUEUES);11031103+ bp->b_flags |= flags & (XBF_READ | XBF_WRITE | XBF_ASYNC | \11041104+ XBF_READ_AHEAD | _XBF_RUN_QUEUES);1072110510731073- BUG_ON(pb->pb_bn == XFS_BUF_DADDR_NULL);11061106+ BUG_ON(bp->b_bn == XFS_BUF_DADDR_NULL);1074110710751108 /* For writes allow an alternate strategy routine to precede10761109 * the actual I/O request (which may not be issued at all in10771110 * a shutdown situation, for example).10781111 */10791079- status = (flags & PBF_WRITE) ?10801080- pagebuf_iostrategy(pb) : pagebuf_iorequest(pb);11121112+ status = (flags & XBF_WRITE) ?11131113+ xfs_buf_iostrategy(bp) : xfs_buf_iorequest(bp);1081111410821115 /* Wait for I/O if we are not an async request.10831116 * Note: async I/O request completion will release the buffer,10841117 * and that can already be done by this point. So using the10851118 * buffer pointer from here on, after async I/O, is invalid.10861119 */10871087- if (!status && !(flags & PBF_ASYNC))10881088- status = pagebuf_iowait(pb);11201120+ if (!status && !(flags & XBF_ASYNC))11211121+ status = xfs_buf_iowait(bp);1089112210901123 return status;10911124}1092112510931093-/*10941094- * Helper routine for pagebuf_iorequest10951095- */10961096-10971126STATIC __inline__ int10981098-_pagebuf_iolocked(10991099- xfs_buf_t *pb)11271127+_xfs_buf_iolocked(11281128+ xfs_buf_t *bp)11001129{11011101- ASSERT(pb->pb_flags & (PBF_READ|PBF_WRITE));11021102- if (pb->pb_flags & PBF_READ)11031103- return pb->pb_locked;11301130+ ASSERT(bp->b_flags & (XBF_READ | XBF_WRITE));11311131+ if (bp->b_flags & XBF_READ)11321132+ return bp->b_locked;11041133 return 0;11051134}1106113511071136STATIC __inline__ void11081108-_pagebuf_iodone(11091109- xfs_buf_t *pb,11371137+_xfs_buf_ioend(11381138+ xfs_buf_t *bp,11101139 int schedule)11111140{11121112- if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {11131113- pb->pb_locked = 0;11141114- pagebuf_iodone(pb, schedule);11411141+ if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {11421142+ bp->b_locked = 0;11431143+ xfs_buf_ioend(bp, schedule);11151144 }11161145}1117114611181147STATIC int11191119-bio_end_io_pagebuf(11481148+xfs_buf_bio_end_io(11201149 struct bio *bio,11211150 unsigned int bytes_done,11221151 int error)11231152{11241124- xfs_buf_t *pb = (xfs_buf_t *)bio->bi_private;11251125- unsigned int blocksize = pb->pb_target->pbr_bsize;11531153+ xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;11541154+ unsigned int blocksize = bp->b_target->bt_bsize;11261155 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;1127115611281157 if (bio->bi_size)11291158 return 1;1130115911311160 if (!test_bit(BIO_UPTODATE, &bio->bi_flags))11321132- pb->pb_error = EIO;11611161+ bp->b_error = EIO;1133116211341163 do {11351164 struct page *page = bvec->bv_page;1136116511371137- if (unlikely(pb->pb_error)) {11381138- if (pb->pb_flags & PBF_READ)11661166+ if (unlikely(bp->b_error)) {11671167+ if (bp->b_flags & XBF_READ)11391168 ClearPageUptodate(page);11401169 SetPageError(page);11411141- } else if (blocksize == PAGE_CACHE_SIZE) {11701170+ } else if (blocksize >= PAGE_CACHE_SIZE) {11421171 SetPageUptodate(page);11431172 } else if (!PagePrivate(page) &&11441144- (pb->pb_flags & _PBF_PAGE_CACHE)) {11731173+ (bp->b_flags & _XBF_PAGE_CACHE)) {11451174 set_page_region(page, bvec->bv_offset, bvec->bv_len);11461175 }1147117611481177 if (--bvec >= bio->bi_io_vec)11491178 prefetchw(&bvec->bv_page->flags);1150117911511151- if (_pagebuf_iolocked(pb)) {11801180+ if (_xfs_buf_iolocked(bp)) {11521181 unlock_page(page);11531182 }11541183 } while (bvec >= bio->bi_io_vec);1155118411561156- _pagebuf_iodone(pb, 1);11851185+ _xfs_buf_ioend(bp, 1);11571186 bio_put(bio);11581187 return 0;11591188}1160118911611190STATIC void11621162-_pagebuf_ioapply(11631163- xfs_buf_t *pb)11911191+_xfs_buf_ioapply(11921192+ xfs_buf_t *bp)11641193{11651194 int i, rw, map_i, total_nr_pages, nr_pages;11661195 struct bio *bio;11671167- int offset = pb->pb_offset;11681168- int size = pb->pb_count_desired;11691169- sector_t sector = pb->pb_bn;11701170- unsigned int blocksize = pb->pb_target->pbr_bsize;11711171- int locking = _pagebuf_iolocked(pb);11961196+ int offset = bp->b_offset;11971197+ int size = bp->b_count_desired;11981198+ sector_t sector = bp->b_bn;11991199+ unsigned int blocksize = bp->b_target->bt_bsize;12001200+ int locking = _xfs_buf_iolocked(bp);1172120111731173- total_nr_pages = pb->pb_page_count;12021202+ total_nr_pages = bp->b_page_count;11741203 map_i = 0;1175120411761176- if (pb->pb_flags & _PBF_RUN_QUEUES) {11771177- pb->pb_flags &= ~_PBF_RUN_QUEUES;11781178- rw = (pb->pb_flags & PBF_READ) ? READ_SYNC : WRITE_SYNC;12051205+ if (bp->b_flags & _XBF_RUN_QUEUES) {12061206+ bp->b_flags &= ~_XBF_RUN_QUEUES;12071207+ rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC;11791208 } else {11801180- rw = (pb->pb_flags & PBF_READ) ? READ : WRITE;12091209+ rw = (bp->b_flags & XBF_READ) ? READ : WRITE;11811210 }1182121111831183- if (pb->pb_flags & PBF_ORDERED) {11841184- ASSERT(!(pb->pb_flags & PBF_READ));12121212+ if (bp->b_flags & XBF_ORDERED) {12131213+ ASSERT(!(bp->b_flags & XBF_READ));11851214 rw = WRITE_BARRIER;11861215 }1187121611881188- /* Special code path for reading a sub page size pagebuf in --12171217+ /* Special code path for reading a sub page size buffer in --11891218 * we populate up the whole page, and hence the other metadata11901219 * in the same page. This optimization is only valid when the11911191- * filesystem block size and the page size are equal.12201220+ * filesystem block size is not smaller than the page size.11921221 */11931193- if ((pb->pb_buffer_length < PAGE_CACHE_SIZE) &&11941194- (pb->pb_flags & PBF_READ) && locking &&11951195- (blocksize == PAGE_CACHE_SIZE)) {12221222+ if ((bp->b_buffer_length < PAGE_CACHE_SIZE) &&12231223+ (bp->b_flags & XBF_READ) && locking &&12241224+ (blocksize >= PAGE_CACHE_SIZE)) {11961225 bio = bio_alloc(GFP_NOIO, 1);1197122611981198- bio->bi_bdev = pb->pb_target->pbr_bdev;12271227+ bio->bi_bdev = bp->b_target->bt_bdev;11991228 bio->bi_sector = sector - (offset >> BBSHIFT);12001200- bio->bi_end_io = bio_end_io_pagebuf;12011201- bio->bi_private = pb;12291229+ bio->bi_end_io = xfs_buf_bio_end_io;12301230+ bio->bi_private = bp;1202123112031203- bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0);12321232+ bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0);12041233 size = 0;1205123412061206- atomic_inc(&pb->pb_io_remaining);12351235+ atomic_inc(&bp->b_io_remaining);1207123612081237 goto submit_io;12091238 }1210123912111240 /* Lock down the pages which we need to for the request */12121212- if (locking && (pb->pb_flags & PBF_WRITE) && (pb->pb_locked == 0)) {12411241+ if (locking && (bp->b_flags & XBF_WRITE) && (bp->b_locked == 0)) {12131242 for (i = 0; size; i++) {12141243 int nbytes = PAGE_CACHE_SIZE - offset;12151215- struct page *page = pb->pb_pages[i];12441244+ struct page *page = bp->b_pages[i];1216124512171246 if (nbytes > size)12181247 nbytes = size;···11971276 size -= nbytes;11981277 offset = 0;11991278 }12001200- offset = pb->pb_offset;12011201- size = pb->pb_count_desired;12791279+ offset = bp->b_offset;12801280+ size = bp->b_count_desired;12021281 }1203128212041283next_chunk:12051205- atomic_inc(&pb->pb_io_remaining);12841284+ atomic_inc(&bp->b_io_remaining);12061285 nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT);12071286 if (nr_pages > total_nr_pages)12081287 nr_pages = total_nr_pages;1209128812101289 bio = bio_alloc(GFP_NOIO, nr_pages);12111211- bio->bi_bdev = pb->pb_target->pbr_bdev;12901290+ bio->bi_bdev = bp->b_target->bt_bdev;12121291 bio->bi_sector = sector;12131213- bio->bi_end_io = bio_end_io_pagebuf;12141214- bio->bi_private = pb;12921292+ bio->bi_end_io = xfs_buf_bio_end_io;12931293+ bio->bi_private = bp;1215129412161295 for (; size && nr_pages; nr_pages--, map_i++) {12171217- int nbytes = PAGE_CACHE_SIZE - offset;12961296+ int rbytes, nbytes = PAGE_CACHE_SIZE - offset;1218129712191298 if (nbytes > size)12201299 nbytes = size;1221130012221222- if (bio_add_page(bio, pb->pb_pages[map_i],12231223- nbytes, offset) < nbytes)13011301+ rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset);13021302+ if (rbytes < nbytes)12241303 break;1225130412261305 offset = 0;···12361315 goto next_chunk;12371316 } else {12381317 bio_put(bio);12391239- pagebuf_ioerror(pb, EIO);13181318+ xfs_buf_ioerror(bp, EIO);12401319 }12411320}1242132112431243-/*12441244- * pagebuf_iorequest -- the core I/O request routine.12451245- */12461322int12471247-pagebuf_iorequest( /* start real I/O */12481248- xfs_buf_t *pb) /* buffer to convey to device */13231323+xfs_buf_iorequest(13241324+ xfs_buf_t *bp)12491325{12501250- PB_TRACE(pb, "iorequest", 0);13261326+ XB_TRACE(bp, "iorequest", 0);1251132712521252- if (pb->pb_flags & PBF_DELWRI) {12531253- pagebuf_delwri_queue(pb, 1);13281328+ if (bp->b_flags & XBF_DELWRI) {13291329+ xfs_buf_delwri_queue(bp, 1);12541330 return 0;12551331 }1256133212571257- if (pb->pb_flags & PBF_WRITE) {12581258- _pagebuf_wait_unpin(pb);13331333+ if (bp->b_flags & XBF_WRITE) {13341334+ xfs_buf_wait_unpin(bp);12591335 }1260133612611261- pagebuf_hold(pb);13371337+ xfs_buf_hold(bp);1262133812631339 /* Set the count to 1 initially, this will stop an I/O12641340 * completion callout which happens before we have started12651265- * all the I/O from calling pagebuf_iodone too early.13411341+ * all the I/O from calling xfs_buf_ioend too early.12661342 */12671267- atomic_set(&pb->pb_io_remaining, 1);12681268- _pagebuf_ioapply(pb);12691269- _pagebuf_iodone(pb, 0);13431343+ atomic_set(&bp->b_io_remaining, 1);13441344+ _xfs_buf_ioapply(bp);13451345+ _xfs_buf_ioend(bp, 0);1270134612711271- pagebuf_rele(pb);13471347+ xfs_buf_rele(bp);12721348 return 0;12731349}1274135012751351/*12761276- * pagebuf_iowait12771277- *12781278- * pagebuf_iowait waits for I/O to complete on the buffer supplied.12791279- * It returns immediately if no I/O is pending. In any case, it returns12801280- * the error code, if any, or 0 if there is no error.13521352+ * Waits for I/O to complete on the buffer supplied.13531353+ * It returns immediately if no I/O is pending.13541354+ * It returns the I/O error code, if any, or 0 if there was no error.12811355 */12821356int12831283-pagebuf_iowait(12841284- xfs_buf_t *pb)13571357+xfs_buf_iowait(13581358+ xfs_buf_t *bp)12851359{12861286- PB_TRACE(pb, "iowait", 0);12871287- if (atomic_read(&pb->pb_io_remaining))12881288- blk_run_address_space(pb->pb_target->pbr_mapping);12891289- down(&pb->pb_iodonesema);12901290- PB_TRACE(pb, "iowaited", (long)pb->pb_error);12911291- return pb->pb_error;13601360+ XB_TRACE(bp, "iowait", 0);13611361+ if (atomic_read(&bp->b_io_remaining))13621362+ blk_run_address_space(bp->b_target->bt_mapping);13631363+ down(&bp->b_iodonesema);13641364+ XB_TRACE(bp, "iowaited", (long)bp->b_error);13651365+ return bp->b_error;12921366}1293136712941294-caddr_t12951295-pagebuf_offset(12961296- xfs_buf_t *pb,13681368+xfs_caddr_t13691369+xfs_buf_offset(13701370+ xfs_buf_t *bp,12971371 size_t offset)12981372{12991373 struct page *page;1300137413011301- offset += pb->pb_offset;13751375+ if (bp->b_flags & XBF_MAPPED)13761376+ return XFS_BUF_PTR(bp) + offset;1302137713031303- page = pb->pb_pages[offset >> PAGE_CACHE_SHIFT];13041304- return (caddr_t) page_address(page) + (offset & (PAGE_CACHE_SIZE - 1));13781378+ offset += bp->b_offset;13791379+ page = bp->b_pages[offset >> PAGE_CACHE_SHIFT];13801380+ return (xfs_caddr_t)page_address(page) + (offset & (PAGE_CACHE_SIZE-1));13051381}1306138213071383/*13081308- * pagebuf_iomove13091309- *13101384 * Move data into or out of a buffer.13111385 */13121386void13131313-pagebuf_iomove(13141314- xfs_buf_t *pb, /* buffer to process */13871387+xfs_buf_iomove(13881388+ xfs_buf_t *bp, /* buffer to process */13151389 size_t boff, /* starting buffer offset */13161390 size_t bsize, /* length to copy */13171391 caddr_t data, /* data address */13181318- page_buf_rw_t mode) /* read/write flag */13921392+ xfs_buf_rw_t mode) /* read/write/zero flag */13191393{13201394 size_t bend, cpoff, csize;13211395 struct page *page;1322139613231397 bend = boff + bsize;13241398 while (boff < bend) {13251325- page = pb->pb_pages[page_buf_btoct(boff + pb->pb_offset)];13261326- cpoff = page_buf_poff(boff + pb->pb_offset);13991399+ page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];14001400+ cpoff = xfs_buf_poff(boff + bp->b_offset);13271401 csize = min_t(size_t,13281328- PAGE_CACHE_SIZE-cpoff, pb->pb_count_desired-boff);14021402+ PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);1329140313301404 ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));1331140513321406 switch (mode) {13331333- case PBRW_ZERO:14071407+ case XBRW_ZERO:13341408 memset(page_address(page) + cpoff, 0, csize);13351409 break;13361336- case PBRW_READ:14101410+ case XBRW_READ:13371411 memcpy(data, page_address(page) + cpoff, csize);13381412 break;13391339- case PBRW_WRITE:14131413+ case XBRW_WRITE:13401414 memcpy(page_address(page) + cpoff, data, csize);13411415 }13421416···13411425}1342142613431427/*13441344- * Handling of buftargs.14281428+ * Handling of buffer targets (buftargs).13451429 */1346143013471431/*13481348- * Wait for any bufs with callbacks that have been submitted but13491349- * have not yet returned... walk the hash list for the target.14321432+ * Wait for any bufs with callbacks that have been submitted but14331433+ * have not yet returned... walk the hash list for the target.13501434 */13511435void13521436xfs_wait_buftarg(···13601444 hash = &btp->bt_hash[i];13611445again:13621446 spin_lock(&hash->bh_lock);13631363- list_for_each_entry_safe(bp, n, &hash->bh_list, pb_hash_list) {13641364- ASSERT(btp == bp->pb_target);13651365- if (!(bp->pb_flags & PBF_FS_MANAGED)) {14471447+ list_for_each_entry_safe(bp, n, &hash->bh_list, b_hash_list) {14481448+ ASSERT(btp == bp->b_target);14491449+ if (!(bp->b_flags & XBF_FS_MANAGED)) {13661450 spin_unlock(&hash->bh_lock);13671451 /*13681452 * Catch superblock reference count leaks13691453 * immediately13701454 */13711371- BUG_ON(bp->pb_bn == 0);14551455+ BUG_ON(bp->b_bn == 0);13721456 delay(100);13731457 goto again;13741458 }···13781462}1379146313801464/*13811381- * Allocate buffer hash table for a given target.13821382- * For devices containing metadata (i.e. not the log/realtime devices)13831383- * we need to allocate a much larger hash table.14651465+ * Allocate buffer hash table for a given target.14661466+ * For devices containing metadata (i.e. not the log/realtime devices)14671467+ * we need to allocate a much larger hash table.13841468 */13851469STATIC void13861470xfs_alloc_bufhash(···14031487xfs_free_bufhash(14041488 xfs_buftarg_t *btp)14051489{14061406- kmem_free(btp->bt_hash,14071407- (1 << btp->bt_hashshift) * sizeof(xfs_bufhash_t));14901490+ kmem_free(btp->bt_hash, (1<<btp->bt_hashshift) * sizeof(xfs_bufhash_t));14081491 btp->bt_hash = NULL;14921492+}14931493+14941494+/*14951495+ * buftarg list for delwrite queue processing14961496+ */14971497+STATIC LIST_HEAD(xfs_buftarg_list);14981498+STATIC DEFINE_SPINLOCK(xfs_buftarg_lock);14991499+15001500+STATIC void15011501+xfs_register_buftarg(15021502+ xfs_buftarg_t *btp)15031503+{15041504+ spin_lock(&xfs_buftarg_lock);15051505+ list_add(&btp->bt_list, &xfs_buftarg_list);15061506+ spin_unlock(&xfs_buftarg_lock);15071507+}15081508+15091509+STATIC void15101510+xfs_unregister_buftarg(15111511+ xfs_buftarg_t *btp)15121512+{15131513+ spin_lock(&xfs_buftarg_lock);15141514+ list_del(&btp->bt_list);15151515+ spin_unlock(&xfs_buftarg_lock);14091516}1410151714111518void···14381499{14391500 xfs_flush_buftarg(btp, 1);14401501 if (external)14411441- xfs_blkdev_put(btp->pbr_bdev);15021502+ xfs_blkdev_put(btp->bt_bdev);14421503 xfs_free_bufhash(btp);14431443- iput(btp->pbr_mapping->host);15041504+ iput(btp->bt_mapping->host);15051505+15061506+ /* Unregister the buftarg first so that we don't get a15071507+ * wakeup finding a non-existent task15081508+ */15091509+ xfs_unregister_buftarg(btp);15101510+ kthread_stop(btp->bt_task);15111511+14441512 kmem_free(btp, sizeof(*btp));14451513}14461514···14581512 unsigned int sectorsize,14591513 int verbose)14601514{14611461- btp->pbr_bsize = blocksize;14621462- btp->pbr_sshift = ffs(sectorsize) - 1;14631463- btp->pbr_smask = sectorsize - 1;15151515+ btp->bt_bsize = blocksize;15161516+ btp->bt_sshift = ffs(sectorsize) - 1;15171517+ btp->bt_smask = sectorsize - 1;1464151814651465- if (set_blocksize(btp->pbr_bdev, sectorsize)) {15191519+ if (set_blocksize(btp->bt_bdev, sectorsize)) {14661520 printk(KERN_WARNING14671521 "XFS: Cannot set_blocksize to %u on device %s\n",14681522 sectorsize, XFS_BUFTARG_NAME(btp));···14821536}1483153714841538/*14851485-* When allocating the initial buffer target we have not yet14861486-* read in the superblock, so don't know what sized sectors14871487-* are being used is at this early stage. Play safe.14881488-*/15391539+ * When allocating the initial buffer target we have not yet15401540+ * read in the superblock, so don't know what sized sectors15411541+ * are being used is at this early stage. Play safe.15421542+ */14891543STATIC int14901544xfs_setsize_buftarg_early(14911545 xfs_buftarg_t *btp,···15331587 mapping->a_ops = &mapping_aops;15341588 mapping->backing_dev_info = bdi;15351589 mapping_set_gfp_mask(mapping, GFP_NOFS);15361536- btp->pbr_mapping = mapping;15901590+ btp->bt_mapping = mapping;15371591 return 0;15921592+}15931593+15941594+STATIC int15951595+xfs_alloc_delwrite_queue(15961596+ xfs_buftarg_t *btp)15971597+{15981598+ int error = 0;15991599+16001600+ INIT_LIST_HEAD(&btp->bt_list);16011601+ INIT_LIST_HEAD(&btp->bt_delwrite_queue);16021602+ spinlock_init(&btp->bt_delwrite_lock, "delwri_lock");16031603+ btp->bt_flags = 0;16041604+ btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd");16051605+ if (IS_ERR(btp->bt_task)) {16061606+ error = PTR_ERR(btp->bt_task);16071607+ goto out_error;16081608+ }16091609+ xfs_register_buftarg(btp);16101610+out_error:16111611+ return error;15381612}1539161315401614xfs_buftarg_t *···1566160015671601 btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);1568160215691569- btp->pbr_dev = bdev->bd_dev;15701570- btp->pbr_bdev = bdev;16031603+ btp->bt_dev = bdev->bd_dev;16041604+ btp->bt_bdev = bdev;15711605 if (xfs_setsize_buftarg_early(btp, bdev))15721606 goto error;15731607 if (xfs_mapping_buftarg(btp, bdev))16081608+ goto error;16091609+ if (xfs_alloc_delwrite_queue(btp))15741610 goto error;15751611 xfs_alloc_bufhash(btp, external);15761612 return btp;···158416161585161715861618/*15871587- * Pagebuf delayed write buffer handling16191619+ * Delayed write buffer handling15881620 */15891589-15901590-STATIC LIST_HEAD(pbd_delwrite_queue);15911591-STATIC DEFINE_SPINLOCK(pbd_delwrite_lock);15921592-15931621STATIC void15941594-pagebuf_delwri_queue(15951595- xfs_buf_t *pb,16221622+xfs_buf_delwri_queue(16231623+ xfs_buf_t *bp,15961624 int unlock)15971625{15981598- PB_TRACE(pb, "delwri_q", (long)unlock);15991599- ASSERT((pb->pb_flags & (PBF_DELWRI|PBF_ASYNC)) ==16001600- (PBF_DELWRI|PBF_ASYNC));16261626+ struct list_head *dwq = &bp->b_target->bt_delwrite_queue;16271627+ spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock;1601162816021602- spin_lock(&pbd_delwrite_lock);16291629+ XB_TRACE(bp, "delwri_q", (long)unlock);16301630+ ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC));16311631+16321632+ spin_lock(dwlk);16031633 /* If already in the queue, dequeue and place at tail */16041604- if (!list_empty(&pb->pb_list)) {16051605- ASSERT(pb->pb_flags & _PBF_DELWRI_Q);16061606- if (unlock) {16071607- atomic_dec(&pb->pb_hold);16081608- }16091609- list_del(&pb->pb_list);16341634+ if (!list_empty(&bp->b_list)) {16351635+ ASSERT(bp->b_flags & _XBF_DELWRI_Q);16361636+ if (unlock)16371637+ atomic_dec(&bp->b_hold);16381638+ list_del(&bp->b_list);16101639 }1611164016121612- pb->pb_flags |= _PBF_DELWRI_Q;16131613- list_add_tail(&pb->pb_list, &pbd_delwrite_queue);16141614- pb->pb_queuetime = jiffies;16151615- spin_unlock(&pbd_delwrite_lock);16411641+ bp->b_flags |= _XBF_DELWRI_Q;16421642+ list_add_tail(&bp->b_list, dwq);16431643+ bp->b_queuetime = jiffies;16441644+ spin_unlock(dwlk);1616164516171646 if (unlock)16181618- pagebuf_unlock(pb);16471647+ xfs_buf_unlock(bp);16191648}1620164916211650void16221622-pagebuf_delwri_dequeue(16231623- xfs_buf_t *pb)16511651+xfs_buf_delwri_dequeue(16521652+ xfs_buf_t *bp)16241653{16541654+ spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock;16251655 int dequeued = 0;1626165616271627- spin_lock(&pbd_delwrite_lock);16281628- if ((pb->pb_flags & PBF_DELWRI) && !list_empty(&pb->pb_list)) {16291629- ASSERT(pb->pb_flags & _PBF_DELWRI_Q);16301630- list_del_init(&pb->pb_list);16571657+ spin_lock(dwlk);16581658+ if ((bp->b_flags & XBF_DELWRI) && !list_empty(&bp->b_list)) {16591659+ ASSERT(bp->b_flags & _XBF_DELWRI_Q);16601660+ list_del_init(&bp->b_list);16311661 dequeued = 1;16321662 }16331633- pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);16341634- spin_unlock(&pbd_delwrite_lock);16631663+ bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);16641664+ spin_unlock(dwlk);1635166516361666 if (dequeued)16371637- pagebuf_rele(pb);16671667+ xfs_buf_rele(bp);1638166816391639- PB_TRACE(pb, "delwri_dq", (long)dequeued);16691669+ XB_TRACE(bp, "delwri_dq", (long)dequeued);16401670}1641167116421672STATIC void16431643-pagebuf_runall_queues(16731673+xfs_buf_runall_queues(16441674 struct workqueue_struct *queue)16451675{16461676 flush_workqueue(queue);16471677}16481648-16491649-/* Defines for pagebuf daemon */16501650-STATIC struct task_struct *xfsbufd_task;16511651-STATIC int xfsbufd_force_flush;16521652-STATIC int xfsbufd_force_sleep;1653167816541679STATIC int16551680xfsbufd_wakeup(16561681 int priority,16571682 gfp_t mask)16581683{16591659- if (xfsbufd_force_sleep)16601660- return 0;16611661- xfsbufd_force_flush = 1;16621662- barrier();16631663- wake_up_process(xfsbufd_task);16841684+ xfs_buftarg_t *btp;16851685+16861686+ spin_lock(&xfs_buftarg_lock);16871687+ list_for_each_entry(btp, &xfs_buftarg_list, bt_list) {16881688+ if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags))16891689+ continue;16901690+ set_bit(XBT_FORCE_FLUSH, &btp->bt_flags);16911691+ wake_up_process(btp->bt_task);16921692+ }16931693+ spin_unlock(&xfs_buftarg_lock);16641694 return 0;16651695}16661696···16681702{16691703 struct list_head tmp;16701704 unsigned long age;16711671- xfs_buftarg_t *target;16721672- xfs_buf_t *pb, *n;17051705+ xfs_buftarg_t *target = (xfs_buftarg_t *)data;17061706+ xfs_buf_t *bp, *n;17071707+ struct list_head *dwq = &target->bt_delwrite_queue;17081708+ spinlock_t *dwlk = &target->bt_delwrite_lock;1673170916741710 current->flags |= PF_MEMALLOC;1675171116761712 INIT_LIST_HEAD(&tmp);16771713 do {16781714 if (unlikely(freezing(current))) {16791679- xfsbufd_force_sleep = 1;17151715+ set_bit(XBT_FORCE_SLEEP, &target->bt_flags);16801716 refrigerator();16811717 } else {16821682- xfsbufd_force_sleep = 0;17181718+ clear_bit(XBT_FORCE_SLEEP, &target->bt_flags);16831719 }1684172016851721 schedule_timeout_interruptible(16861722 xfs_buf_timer_centisecs * msecs_to_jiffies(10));1687172316881724 age = xfs_buf_age_centisecs * msecs_to_jiffies(10);16891689- spin_lock(&pbd_delwrite_lock);16901690- list_for_each_entry_safe(pb, n, &pbd_delwrite_queue, pb_list) {16911691- PB_TRACE(pb, "walkq1", (long)pagebuf_ispin(pb));16921692- ASSERT(pb->pb_flags & PBF_DELWRI);17251725+ spin_lock(dwlk);17261726+ list_for_each_entry_safe(bp, n, dwq, b_list) {17271727+ XB_TRACE(bp, "walkq1", (long)xfs_buf_ispin(bp));17281728+ ASSERT(bp->b_flags & XBF_DELWRI);1693172916941694- if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {16951695- if (!xfsbufd_force_flush &&17301730+ if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {17311731+ if (!test_bit(XBT_FORCE_FLUSH,17321732+ &target->bt_flags) &&16961733 time_before(jiffies,16971697- pb->pb_queuetime + age)) {16981698- pagebuf_unlock(pb);17341734+ bp->b_queuetime + age)) {17351735+ xfs_buf_unlock(bp);16991736 break;17001737 }1701173817021702- pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);17031703- pb->pb_flags |= PBF_WRITE;17041704- list_move(&pb->pb_list, &tmp);17391739+ bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);17401740+ bp->b_flags |= XBF_WRITE;17411741+ list_move(&bp->b_list, &tmp);17051742 }17061743 }17071707- spin_unlock(&pbd_delwrite_lock);17441744+ spin_unlock(dwlk);1708174517091746 while (!list_empty(&tmp)) {17101710- pb = list_entry(tmp.next, xfs_buf_t, pb_list);17111711- target = pb->pb_target;17471747+ bp = list_entry(tmp.next, xfs_buf_t, b_list);17481748+ ASSERT(target == bp->b_target);1712174917131713- list_del_init(&pb->pb_list);17141714- pagebuf_iostrategy(pb);17501750+ list_del_init(&bp->b_list);17511751+ xfs_buf_iostrategy(bp);1715175217161716- blk_run_address_space(target->pbr_mapping);17531753+ blk_run_address_space(target->bt_mapping);17171754 }1718175517191756 if (as_list_len > 0)17201757 purge_addresses();1721175817221722- xfsbufd_force_flush = 0;17591759+ clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);17231760 } while (!kthread_should_stop());1724176117251762 return 0;17261763}1727176417281765/*17291729- * Go through all incore buffers, and release buffers if they belong to17301730- * the given device. This is used in filesystem error handling to17311731- * preserve the consistency of its metadata.17661766+ * Go through all incore buffers, and release buffers if they belong to17671767+ * the given device. This is used in filesystem error handling to17681768+ * preserve the consistency of its metadata.17321769 */17331770int17341771xfs_flush_buftarg(···17391770 int wait)17401771{17411772 struct list_head tmp;17421742- xfs_buf_t *pb, *n;17731773+ xfs_buf_t *bp, *n;17431774 int pincount = 0;17751775+ struct list_head *dwq = &target->bt_delwrite_queue;17761776+ spinlock_t *dwlk = &target->bt_delwrite_lock;1744177717451745- pagebuf_runall_queues(xfsdatad_workqueue);17461746- pagebuf_runall_queues(xfslogd_workqueue);17781778+ xfs_buf_runall_queues(xfsdatad_workqueue);17791779+ xfs_buf_runall_queues(xfslogd_workqueue);1747178017481781 INIT_LIST_HEAD(&tmp);17491749- spin_lock(&pbd_delwrite_lock);17501750- list_for_each_entry_safe(pb, n, &pbd_delwrite_queue, pb_list) {17511751-17521752- if (pb->pb_target != target)17531753- continue;17541754-17551755- ASSERT(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q));17561756- PB_TRACE(pb, "walkq2", (long)pagebuf_ispin(pb));17571757- if (pagebuf_ispin(pb)) {17821782+ spin_lock(dwlk);17831783+ list_for_each_entry_safe(bp, n, dwq, b_list) {17841784+ ASSERT(bp->b_target == target);17851785+ ASSERT(bp->b_flags & (XBF_DELWRI | _XBF_DELWRI_Q));17861786+ XB_TRACE(bp, "walkq2", (long)xfs_buf_ispin(bp));17871787+ if (xfs_buf_ispin(bp)) {17581788 pincount++;17591789 continue;17601790 }1761179117621762- list_move(&pb->pb_list, &tmp);17921792+ list_move(&bp->b_list, &tmp);17631793 }17641764- spin_unlock(&pbd_delwrite_lock);17941794+ spin_unlock(dwlk);1765179517661796 /*17671797 * Dropped the delayed write list lock, now walk the temporary list17681798 */17691769- list_for_each_entry_safe(pb, n, &tmp, pb_list) {17701770- pagebuf_lock(pb);17711771- pb->pb_flags &= ~(PBF_DELWRI|_PBF_DELWRI_Q);17721772- pb->pb_flags |= PBF_WRITE;17991799+ list_for_each_entry_safe(bp, n, &tmp, b_list) {18001800+ xfs_buf_lock(bp);18011801+ bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);18021802+ bp->b_flags |= XBF_WRITE;17731803 if (wait)17741774- pb->pb_flags &= ~PBF_ASYNC;18041804+ bp->b_flags &= ~XBF_ASYNC;17751805 else17761776- list_del_init(&pb->pb_list);18061806+ list_del_init(&bp->b_list);1777180717781778- pagebuf_iostrategy(pb);18081808+ xfs_buf_iostrategy(bp);17791809 }1780181017811811 /*17821812 * Remaining list items must be flushed before returning17831813 */17841814 while (!list_empty(&tmp)) {17851785- pb = list_entry(tmp.next, xfs_buf_t, pb_list);18151815+ bp = list_entry(tmp.next, xfs_buf_t, b_list);1786181617871787- list_del_init(&pb->pb_list);17881788- xfs_iowait(pb);17891789- xfs_buf_relse(pb);18171817+ list_del_init(&bp->b_list);18181818+ xfs_iowait(bp);18191819+ xfs_buf_relse(bp);17901820 }1791182117921822 if (wait)17931793- blk_run_address_space(target->pbr_mapping);18231823+ blk_run_address_space(target->bt_mapping);1794182417951825 return pincount;17961826}1797182717981828int __init17991799-pagebuf_init(void)18291829+xfs_buf_init(void)18001830{18011831 int error = -ENOMEM;1802183218031803-#ifdef PAGEBUF_TRACE18041804- pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);18331833+#ifdef XFS_BUF_TRACE18341834+ xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP);18051835#endif1806183618071807- pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");18081808- if (!pagebuf_zone)18371837+ xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");18381838+ if (!xfs_buf_zone)18091839 goto out_free_trace_buf;1810184018111841 xfslogd_workqueue = create_workqueue("xfslogd");···18151847 if (!xfsdatad_workqueue)18161848 goto out_destroy_xfslogd_workqueue;1817184918181818- xfsbufd_task = kthread_run(xfsbufd, NULL, "xfsbufd");18191819- if (IS_ERR(xfsbufd_task)) {18201820- error = PTR_ERR(xfsbufd_task);18501850+ xfs_buf_shake = kmem_shake_register(xfsbufd_wakeup);18511851+ if (!xfs_buf_shake)18211852 goto out_destroy_xfsdatad_workqueue;18221822- }18231823-18241824- pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);18251825- if (!pagebuf_shake)18261826- goto out_stop_xfsbufd;1827185318281854 return 0;1829185518301830- out_stop_xfsbufd:18311831- kthread_stop(xfsbufd_task);18321856 out_destroy_xfsdatad_workqueue:18331857 destroy_workqueue(xfsdatad_workqueue);18341858 out_destroy_xfslogd_workqueue:18351859 destroy_workqueue(xfslogd_workqueue);18361860 out_free_buf_zone:18371837- kmem_zone_destroy(pagebuf_zone);18611861+ kmem_zone_destroy(xfs_buf_zone);18381862 out_free_trace_buf:18391839-#ifdef PAGEBUF_TRACE18401840- ktrace_free(pagebuf_trace_buf);18631863+#ifdef XFS_BUF_TRACE18641864+ ktrace_free(xfs_buf_trace_buf);18411865#endif18421866 return error;18431867}1844186818451869void18461846-pagebuf_terminate(void)18701870+xfs_buf_terminate(void)18471871{18481848- kmem_shake_deregister(pagebuf_shake);18491849- kthread_stop(xfsbufd_task);18721872+ kmem_shake_deregister(xfs_buf_shake);18501873 destroy_workqueue(xfsdatad_workqueue);18511874 destroy_workqueue(xfslogd_workqueue);18521852- kmem_zone_destroy(pagebuf_zone);18531853-#ifdef PAGEBUF_TRACE18541854- ktrace_free(pagebuf_trace_buf);18751875+ kmem_zone_destroy(xfs_buf_zone);18761876+#ifdef XFS_BUF_TRACE18771877+ ktrace_free(xfs_buf_trace_buf);18551878#endif18561879}
+262-386
fs/xfs/linux-2.6/xfs_buf.h
···3232 * Base types3333 */34343535-#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))3535+#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))36363737-#define page_buf_ctob(pp) ((pp) * PAGE_CACHE_SIZE)3838-#define page_buf_btoc(dd) (((dd) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)3939-#define page_buf_btoct(dd) ((dd) >> PAGE_CACHE_SHIFT)4040-#define page_buf_poff(aa) ((aa) & ~PAGE_CACHE_MASK)3737+#define xfs_buf_ctob(pp) ((pp) * PAGE_CACHE_SIZE)3838+#define xfs_buf_btoc(dd) (((dd) + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT)3939+#define xfs_buf_btoct(dd) ((dd) >> PAGE_CACHE_SHIFT)4040+#define xfs_buf_poff(aa) ((aa) & ~PAGE_CACHE_MASK)41414242-typedef enum page_buf_rw_e {4343- PBRW_READ = 1, /* transfer into target memory */4444- PBRW_WRITE = 2, /* transfer from target memory */4545- PBRW_ZERO = 3 /* Zero target memory */4646-} page_buf_rw_t;4242+typedef enum {4343+ XBRW_READ = 1, /* transfer into target memory */4444+ XBRW_WRITE = 2, /* transfer from target memory */4545+ XBRW_ZERO = 3, /* Zero target memory */4646+} xfs_buf_rw_t;47474848-4949-typedef enum page_buf_flags_e { /* pb_flags values */5050- PBF_READ = (1 << 0), /* buffer intended for reading from device */5151- PBF_WRITE = (1 << 1), /* buffer intended for writing to device */5252- PBF_MAPPED = (1 << 2), /* buffer mapped (pb_addr valid) */5353- PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */5454- PBF_DONE = (1 << 5), /* all pages in the buffer uptodate */5555- PBF_DELWRI = (1 << 6), /* buffer has dirty pages */5656- PBF_STALE = (1 << 7), /* buffer has been staled, do not find it */5757- PBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */5858- PBF_ORDERED = (1 << 11), /* use ordered writes */5959- PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */4848+typedef enum {4949+ XBF_READ = (1 << 0), /* buffer intended for reading from device */5050+ XBF_WRITE = (1 << 1), /* buffer intended for writing to device */5151+ XBF_MAPPED = (1 << 2), /* buffer mapped (b_addr valid) */5252+ XBF_ASYNC = (1 << 4), /* initiator will not wait for completion */5353+ XBF_DONE = (1 << 5), /* all pages in the buffer uptodate */5454+ XBF_DELWRI = (1 << 6), /* buffer has dirty pages */5555+ XBF_STALE = (1 << 7), /* buffer has been staled, do not find it */5656+ XBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */5757+ XBF_ORDERED = (1 << 11), /* use ordered writes */5858+ XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */60596160 /* flags used only as arguments to access routines */6262- PBF_LOCK = (1 << 14), /* lock requested */6363- PBF_TRYLOCK = (1 << 15), /* lock requested, but do not wait */6464- PBF_DONT_BLOCK = (1 << 16), /* do not block in current thread */6161+ XBF_LOCK = (1 << 14), /* lock requested */6262+ XBF_TRYLOCK = (1 << 15), /* lock requested, but do not wait */6363+ XBF_DONT_BLOCK = (1 << 16), /* do not block in current thread */65646665 /* flags used only internally */6767- _PBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */6868- _PBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */6969- _PBF_RUN_QUEUES = (1 << 19),/* run block device task queue */7070- _PBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */7171-} page_buf_flags_t;6666+ _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */6767+ _XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */6868+ _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */6969+ _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */7070+} xfs_buf_flags_t;72717272+typedef enum {7373+ XBT_FORCE_SLEEP = (0 << 1),7474+ XBT_FORCE_FLUSH = (1 << 1),7575+} xfs_buftarg_flags_t;73767477typedef struct xfs_bufhash {7578 struct list_head bh_list;···8077} xfs_bufhash_t;81788279typedef struct xfs_buftarg {8383- dev_t pbr_dev;8484- struct block_device *pbr_bdev;8585- struct address_space *pbr_mapping;8686- unsigned int pbr_bsize;8787- unsigned int pbr_sshift;8888- size_t pbr_smask;8080+ dev_t bt_dev;8181+ struct block_device *bt_bdev;8282+ struct address_space *bt_mapping;8383+ unsigned int bt_bsize;8484+ unsigned int bt_sshift;8585+ size_t bt_smask;89869090- /* per-device buffer hash table */8787+ /* per device buffer hash table */9188 uint bt_hashmask;9289 uint bt_hashshift;9390 xfs_bufhash_t *bt_hash;9191+9292+ /* per device delwri queue */9393+ struct task_struct *bt_task;9494+ struct list_head bt_list;9595+ struct list_head bt_delwrite_queue;9696+ spinlock_t bt_delwrite_lock;9797+ unsigned long bt_flags;9498} xfs_buftarg_t;959996100/*9797- * xfs_buf_t: Buffer structure for page cache-based buffers101101+ * xfs_buf_t: Buffer structure for pagecache-based buffers98102 *9999- * This buffer structure is used by the page cache buffer management routines100100- * to refer to an assembly of pages forming a logical buffer. The actual I/O101101- * is performed with buffer_head structures, as required by drivers.102102- * 103103- * The buffer structure is used on temporary basis only, and discarded when104104- * released. The real data storage is recorded in the page cache. Metadata is103103+ * This buffer structure is used by the pagecache buffer management routines104104+ * to refer to an assembly of pages forming a logical buffer.105105+ *106106+ * The buffer structure is used on a temporary basis only, and discarded when107107+ * released. The real data storage is recorded in the pagecache. Buffers are105108 * hashed to the block device on which the file system resides.106109 */107110108111struct xfs_buf;112112+typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);113113+typedef void (*xfs_buf_relse_t)(struct xfs_buf *);114114+typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *);109115110110-/* call-back function on I/O completion */111111-typedef void (*page_buf_iodone_t)(struct xfs_buf *);112112-/* call-back function on I/O completion */113113-typedef void (*page_buf_relse_t)(struct xfs_buf *);114114-/* pre-write function */115115-typedef int (*page_buf_bdstrat_t)(struct xfs_buf *);116116-117117-#define PB_PAGES 2116116+#define XB_PAGES 2118117119118typedef struct xfs_buf {120120- struct semaphore pb_sema; /* semaphore for lockables */121121- unsigned long pb_queuetime; /* time buffer was queued */122122- atomic_t pb_pin_count; /* pin count */123123- wait_queue_head_t pb_waiters; /* unpin waiters */124124- struct list_head pb_list;125125- page_buf_flags_t pb_flags; /* status flags */126126- struct list_head pb_hash_list; /* hash table list */127127- xfs_bufhash_t *pb_hash; /* hash table list start */128128- xfs_buftarg_t *pb_target; /* buffer target (device) */129129- atomic_t pb_hold; /* reference count */130130- xfs_daddr_t pb_bn; /* block number for I/O */131131- loff_t pb_file_offset; /* offset in file */132132- size_t pb_buffer_length; /* size of buffer in bytes */133133- size_t pb_count_desired; /* desired transfer size */134134- void *pb_addr; /* virtual address of buffer */135135- struct work_struct pb_iodone_work;136136- atomic_t pb_io_remaining;/* #outstanding I/O requests */137137- page_buf_iodone_t pb_iodone; /* I/O completion function */138138- page_buf_relse_t pb_relse; /* releasing function */139139- page_buf_bdstrat_t pb_strat; /* pre-write function */140140- struct semaphore pb_iodonesema; /* Semaphore for I/O waiters */141141- void *pb_fspriv;142142- void *pb_fspriv2;143143- void *pb_fspriv3;144144- unsigned short pb_error; /* error code on I/O */145145- unsigned short pb_locked; /* page array is locked */146146- unsigned int pb_page_count; /* size of page array */147147- unsigned int pb_offset; /* page offset in first page */148148- struct page **pb_pages; /* array of page pointers */149149- struct page *pb_page_array[PB_PAGES]; /* inline pages */150150-#ifdef PAGEBUF_LOCK_TRACKING151151- int pb_last_holder;119119+ struct semaphore b_sema; /* semaphore for lockables */120120+ unsigned long b_queuetime; /* time buffer was queued */121121+ atomic_t b_pin_count; /* pin count */122122+ wait_queue_head_t b_waiters; /* unpin waiters */123123+ struct list_head b_list;124124+ xfs_buf_flags_t b_flags; /* status flags */125125+ struct list_head b_hash_list; /* hash table list */126126+ xfs_bufhash_t *b_hash; /* hash table list start */127127+ xfs_buftarg_t *b_target; /* buffer target (device) */128128+ atomic_t b_hold; /* reference count */129129+ xfs_daddr_t b_bn; /* block number for I/O */130130+ xfs_off_t b_file_offset; /* offset in file */131131+ size_t b_buffer_length;/* size of buffer in bytes */132132+ size_t b_count_desired;/* desired transfer size */133133+ void *b_addr; /* virtual address of buffer */134134+ struct work_struct b_iodone_work;135135+ atomic_t b_io_remaining; /* #outstanding I/O requests */136136+ xfs_buf_iodone_t b_iodone; /* I/O completion function */137137+ xfs_buf_relse_t b_relse; /* releasing function */138138+ xfs_buf_bdstrat_t b_strat; /* pre-write function */139139+ struct semaphore b_iodonesema; /* Semaphore for I/O waiters */140140+ void *b_fspriv;141141+ void *b_fspriv2;142142+ void *b_fspriv3;143143+ unsigned short b_error; /* error code on I/O */144144+ unsigned short b_locked; /* page array is locked */145145+ unsigned int b_page_count; /* size of page array */146146+ unsigned int b_offset; /* page offset in first page */147147+ struct page **b_pages; /* array of page pointers */148148+ struct page *b_page_array[XB_PAGES]; /* inline pages */149149+#ifdef XFS_BUF_LOCK_TRACKING150150+ int b_last_holder;152151#endif153152} xfs_buf_t;154153155154156155/* Finding and Reading Buffers */157157-158158-extern xfs_buf_t *_pagebuf_find( /* find buffer for block if */159159- /* the block is in memory */160160- xfs_buftarg_t *, /* inode for block */161161- loff_t, /* starting offset of range */162162- size_t, /* length of range */163163- page_buf_flags_t, /* PBF_LOCK */164164- xfs_buf_t *); /* newly allocated buffer */165165-156156+extern xfs_buf_t *_xfs_buf_find(xfs_buftarg_t *, xfs_off_t, size_t,157157+ xfs_buf_flags_t, xfs_buf_t *);166158#define xfs_incore(buftarg,blkno,len,lockit) \167167- _pagebuf_find(buftarg, blkno ,len, lockit, NULL)159159+ _xfs_buf_find(buftarg, blkno ,len, lockit, NULL)168160169169-extern xfs_buf_t *xfs_buf_get_flags( /* allocate a buffer */170170- xfs_buftarg_t *, /* inode for buffer */171171- loff_t, /* starting offset of range */172172- size_t, /* length of range */173173- page_buf_flags_t); /* PBF_LOCK, PBF_READ, */174174- /* PBF_ASYNC */175175-161161+extern xfs_buf_t *xfs_buf_get_flags(xfs_buftarg_t *, xfs_off_t, size_t,162162+ xfs_buf_flags_t);176163#define xfs_buf_get(target, blkno, len, flags) \177177- xfs_buf_get_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)164164+ xfs_buf_get_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)178165179179-extern xfs_buf_t *xfs_buf_read_flags( /* allocate and read a buffer */180180- xfs_buftarg_t *, /* inode for buffer */181181- loff_t, /* starting offset of range */182182- size_t, /* length of range */183183- page_buf_flags_t); /* PBF_LOCK, PBF_ASYNC */184184-166166+extern xfs_buf_t *xfs_buf_read_flags(xfs_buftarg_t *, xfs_off_t, size_t,167167+ xfs_buf_flags_t);185168#define xfs_buf_read(target, blkno, len, flags) \186186- xfs_buf_read_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)169169+ xfs_buf_read_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)187170188188-extern xfs_buf_t *pagebuf_get_empty( /* allocate pagebuf struct with */189189- /* no memory or disk address */190190- size_t len,191191- xfs_buftarg_t *); /* mount point "fake" inode */192192-193193-extern xfs_buf_t *pagebuf_get_no_daddr(/* allocate pagebuf struct */194194- /* without disk address */195195- size_t len,196196- xfs_buftarg_t *); /* mount point "fake" inode */197197-198198-extern int pagebuf_associate_memory(199199- xfs_buf_t *,200200- void *,201201- size_t);202202-203203-extern void pagebuf_hold( /* increment reference count */204204- xfs_buf_t *); /* buffer to hold */205205-206206-extern void pagebuf_readahead( /* read ahead into cache */207207- xfs_buftarg_t *, /* target for buffer (or NULL) */208208- loff_t, /* starting offset of range */209209- size_t, /* length of range */210210- page_buf_flags_t); /* additional read flags */171171+extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *);172172+extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *);173173+extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t);174174+extern void xfs_buf_hold(xfs_buf_t *);175175+extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t,176176+ xfs_buf_flags_t);211177212178/* Releasing Buffers */213213-214214-extern void pagebuf_free( /* deallocate a buffer */215215- xfs_buf_t *); /* buffer to deallocate */216216-217217-extern void pagebuf_rele( /* release hold on a buffer */218218- xfs_buf_t *); /* buffer to release */179179+extern void xfs_buf_free(xfs_buf_t *);180180+extern void xfs_buf_rele(xfs_buf_t *);219181220182/* Locking and Unlocking Buffers */221221-222222-extern int pagebuf_cond_lock( /* lock buffer, if not locked */223223- /* (returns -EBUSY if locked) */224224- xfs_buf_t *); /* buffer to lock */225225-226226-extern int pagebuf_lock_value( /* return count on lock */227227- xfs_buf_t *); /* buffer to check */228228-229229-extern int pagebuf_lock( /* lock buffer */230230- xfs_buf_t *); /* buffer to lock */231231-232232-extern void pagebuf_unlock( /* unlock buffer */233233- xfs_buf_t *); /* buffer to unlock */183183+extern int xfs_buf_cond_lock(xfs_buf_t *);184184+extern int xfs_buf_lock_value(xfs_buf_t *);185185+extern void xfs_buf_lock(xfs_buf_t *);186186+extern void xfs_buf_unlock(xfs_buf_t *);234187235188/* Buffer Read and Write Routines */189189+extern void xfs_buf_ioend(xfs_buf_t *, int);190190+extern void xfs_buf_ioerror(xfs_buf_t *, int);191191+extern int xfs_buf_iostart(xfs_buf_t *, xfs_buf_flags_t);192192+extern int xfs_buf_iorequest(xfs_buf_t *);193193+extern int xfs_buf_iowait(xfs_buf_t *);194194+extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, xfs_caddr_t,195195+ xfs_buf_rw_t);236196237237-extern void pagebuf_iodone( /* mark buffer I/O complete */238238- xfs_buf_t *, /* buffer to mark */239239- int); /* run completion locally, or in240240- * a helper thread. */241241-242242-extern void pagebuf_ioerror( /* mark buffer in error (or not) */243243- xfs_buf_t *, /* buffer to mark */244244- int); /* error to store (0 if none) */245245-246246-extern int pagebuf_iostart( /* start I/O on a buffer */247247- xfs_buf_t *, /* buffer to start */248248- page_buf_flags_t); /* PBF_LOCK, PBF_ASYNC, */249249- /* PBF_READ, PBF_WRITE, */250250- /* PBF_DELWRI */251251-252252-extern int pagebuf_iorequest( /* start real I/O */253253- xfs_buf_t *); /* buffer to convey to device */254254-255255-extern int pagebuf_iowait( /* wait for buffer I/O done */256256- xfs_buf_t *); /* buffer to wait on */257257-258258-extern void pagebuf_iomove( /* move data in/out of pagebuf */259259- xfs_buf_t *, /* buffer to manipulate */260260- size_t, /* starting buffer offset */261261- size_t, /* length in buffer */262262- caddr_t, /* data pointer */263263- page_buf_rw_t); /* direction */264264-265265-static inline int pagebuf_iostrategy(xfs_buf_t *pb)197197+static inline int xfs_buf_iostrategy(xfs_buf_t *bp)266198{267267- return pb->pb_strat ? pb->pb_strat(pb) : pagebuf_iorequest(pb);199199+ return bp->b_strat ? bp->b_strat(bp) : xfs_buf_iorequest(bp);268200}269201270270-static inline int pagebuf_geterror(xfs_buf_t *pb)202202+static inline int xfs_buf_geterror(xfs_buf_t *bp)271203{272272- return pb ? pb->pb_error : ENOMEM;204204+ return bp ? bp->b_error : ENOMEM;273205}274206275207/* Buffer Utility Routines */276276-277277-extern caddr_t pagebuf_offset( /* pointer at offset in buffer */278278- xfs_buf_t *, /* buffer to offset into */279279- size_t); /* offset */208208+extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t);280209281210/* Pinning Buffer Storage in Memory */282282-283283-extern void pagebuf_pin( /* pin buffer in memory */284284- xfs_buf_t *); /* buffer to pin */285285-286286-extern void pagebuf_unpin( /* unpin buffered data */287287- xfs_buf_t *); /* buffer to unpin */288288-289289-extern int pagebuf_ispin( /* check if buffer is pinned */290290- xfs_buf_t *); /* buffer to check */211211+extern void xfs_buf_pin(xfs_buf_t *);212212+extern void xfs_buf_unpin(xfs_buf_t *);213213+extern int xfs_buf_ispin(xfs_buf_t *);291214292215/* Delayed Write Buffer Routines */293293-294294-extern void pagebuf_delwri_dequeue(xfs_buf_t *);216216+extern void xfs_buf_delwri_dequeue(xfs_buf_t *);295217296218/* Buffer Daemon Setup Routines */219219+extern int xfs_buf_init(void);220220+extern void xfs_buf_terminate(void);297221298298-extern int pagebuf_init(void);299299-extern void pagebuf_terminate(void);300300-301301-302302-#ifdef PAGEBUF_TRACE303303-extern ktrace_t *pagebuf_trace_buf;304304-extern void pagebuf_trace(305305- xfs_buf_t *, /* buffer being traced */306306- char *, /* description of operation */307307- void *, /* arbitrary diagnostic value */308308- void *); /* return address */222222+#ifdef XFS_BUF_TRACE223223+extern ktrace_t *xfs_buf_trace_buf;224224+extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);309225#else310310-# define pagebuf_trace(pb, id, ptr, ra) do { } while (0)226226+#define xfs_buf_trace(bp,id,ptr,ra) do { } while (0)311227#endif312228313313-#define pagebuf_target_name(target) \314314- ({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; })229229+#define xfs_buf_target_name(target) \230230+ ({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; })315231316232233233+#define XFS_B_ASYNC XBF_ASYNC234234+#define XFS_B_DELWRI XBF_DELWRI235235+#define XFS_B_READ XBF_READ236236+#define XFS_B_WRITE XBF_WRITE237237+#define XFS_B_STALE XBF_STALE317238318318-/* These are just for xfs_syncsub... it sets an internal variable319319- * then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t320320- */321321-#define XFS_B_ASYNC PBF_ASYNC322322-#define XFS_B_DELWRI PBF_DELWRI323323-#define XFS_B_READ PBF_READ324324-#define XFS_B_WRITE PBF_WRITE325325-#define XFS_B_STALE PBF_STALE239239+#define XFS_BUF_TRYLOCK XBF_TRYLOCK240240+#define XFS_INCORE_TRYLOCK XBF_TRYLOCK241241+#define XFS_BUF_LOCK XBF_LOCK242242+#define XFS_BUF_MAPPED XBF_MAPPED326243327327-#define XFS_BUF_TRYLOCK PBF_TRYLOCK328328-#define XFS_INCORE_TRYLOCK PBF_TRYLOCK329329-#define XFS_BUF_LOCK PBF_LOCK330330-#define XFS_BUF_MAPPED PBF_MAPPED244244+#define BUF_BUSY XBF_DONT_BLOCK331245332332-#define BUF_BUSY PBF_DONT_BLOCK246246+#define XFS_BUF_BFLAGS(bp) ((bp)->b_flags)247247+#define XFS_BUF_ZEROFLAGS(bp) \248248+ ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI))333249334334-#define XFS_BUF_BFLAGS(x) ((x)->pb_flags)335335-#define XFS_BUF_ZEROFLAGS(x) \336336- ((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI))337337-338338-#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)339339-#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)340340-#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)341341-#define XFS_BUF_SUPER_STALE(x) do { \342342- XFS_BUF_STALE(x); \343343- pagebuf_delwri_dequeue(x); \344344- XFS_BUF_DONE(x); \250250+#define XFS_BUF_STALE(bp) ((bp)->b_flags |= XFS_B_STALE)251251+#define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XFS_B_STALE)252252+#define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XFS_B_STALE)253253+#define XFS_BUF_SUPER_STALE(bp) do { \254254+ XFS_BUF_STALE(bp); \255255+ xfs_buf_delwri_dequeue(bp); \256256+ XFS_BUF_DONE(bp); \345257 } while (0)346258347347-#define XFS_BUF_MANAGE PBF_FS_MANAGED348348-#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED)259259+#define XFS_BUF_MANAGE XBF_FS_MANAGED260260+#define XFS_BUF_UNMANAGE(bp) ((bp)->b_flags &= ~XBF_FS_MANAGED)349261350350-#define XFS_BUF_DELAYWRITE(x) ((x)->pb_flags |= PBF_DELWRI)351351-#define XFS_BUF_UNDELAYWRITE(x) pagebuf_delwri_dequeue(x)352352-#define XFS_BUF_ISDELAYWRITE(x) ((x)->pb_flags & PBF_DELWRI)262262+#define XFS_BUF_DELAYWRITE(bp) ((bp)->b_flags |= XBF_DELWRI)263263+#define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp)264264+#define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI)353265354354-#define XFS_BUF_ERROR(x,no) pagebuf_ioerror(x,no)355355-#define XFS_BUF_GETERROR(x) pagebuf_geterror(x)356356-#define XFS_BUF_ISERROR(x) (pagebuf_geterror(x)?1:0)266266+#define XFS_BUF_ERROR(bp,no) xfs_buf_ioerror(bp,no)267267+#define XFS_BUF_GETERROR(bp) xfs_buf_geterror(bp)268268+#define XFS_BUF_ISERROR(bp) (xfs_buf_geterror(bp) ? 1 : 0)357269358358-#define XFS_BUF_DONE(x) ((x)->pb_flags |= PBF_DONE)359359-#define XFS_BUF_UNDONE(x) ((x)->pb_flags &= ~PBF_DONE)360360-#define XFS_BUF_ISDONE(x) ((x)->pb_flags & PBF_DONE)270270+#define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE)271271+#define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE)272272+#define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE)361273362362-#define XFS_BUF_BUSY(x) do { } while (0)363363-#define XFS_BUF_UNBUSY(x) do { } while (0)364364-#define XFS_BUF_ISBUSY(x) (1)274274+#define XFS_BUF_BUSY(bp) do { } while (0)275275+#define XFS_BUF_UNBUSY(bp) do { } while (0)276276+#define XFS_BUF_ISBUSY(bp) (1)365277366366-#define XFS_BUF_ASYNC(x) ((x)->pb_flags |= PBF_ASYNC)367367-#define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC)368368-#define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC)278278+#define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC)279279+#define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC)280280+#define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC)369281370370-#define XFS_BUF_ORDERED(x) ((x)->pb_flags |= PBF_ORDERED)371371-#define XFS_BUF_UNORDERED(x) ((x)->pb_flags &= ~PBF_ORDERED)372372-#define XFS_BUF_ISORDERED(x) ((x)->pb_flags & PBF_ORDERED)282282+#define XFS_BUF_ORDERED(bp) ((bp)->b_flags |= XBF_ORDERED)283283+#define XFS_BUF_UNORDERED(bp) ((bp)->b_flags &= ~XBF_ORDERED)284284+#define XFS_BUF_ISORDERED(bp) ((bp)->b_flags & XBF_ORDERED)373285374374-#define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n")375375-#define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n")376376-#define XFS_BUF_ISSHUT(x) (0)286286+#define XFS_BUF_SHUT(bp) do { } while (0)287287+#define XFS_BUF_UNSHUT(bp) do { } while (0)288288+#define XFS_BUF_ISSHUT(bp) (0)377289378378-#define XFS_BUF_HOLD(x) pagebuf_hold(x)379379-#define XFS_BUF_READ(x) ((x)->pb_flags |= PBF_READ)380380-#define XFS_BUF_UNREAD(x) ((x)->pb_flags &= ~PBF_READ)381381-#define XFS_BUF_ISREAD(x) ((x)->pb_flags & PBF_READ)290290+#define XFS_BUF_HOLD(bp) xfs_buf_hold(bp)291291+#define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ)292292+#define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ)293293+#define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ)382294383383-#define XFS_BUF_WRITE(x) ((x)->pb_flags |= PBF_WRITE)384384-#define XFS_BUF_UNWRITE(x) ((x)->pb_flags &= ~PBF_WRITE)385385-#define XFS_BUF_ISWRITE(x) ((x)->pb_flags & PBF_WRITE)295295+#define XFS_BUF_WRITE(bp) ((bp)->b_flags |= XBF_WRITE)296296+#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE)297297+#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE)386298387387-#define XFS_BUF_ISUNINITIAL(x) (0)388388-#define XFS_BUF_UNUNINITIAL(x) (0)299299+#define XFS_BUF_ISUNINITIAL(bp) (0)300300+#define XFS_BUF_UNUNINITIAL(bp) (0)389301390390-#define XFS_BUF_BP_ISMAPPED(bp) 1302302+#define XFS_BUF_BP_ISMAPPED(bp) (1)391303392392-#define XFS_BUF_IODONE_FUNC(buf) (buf)->pb_iodone393393-#define XFS_BUF_SET_IODONE_FUNC(buf, func) \394394- (buf)->pb_iodone = (func)395395-#define XFS_BUF_CLR_IODONE_FUNC(buf) \396396- (buf)->pb_iodone = NULL397397-#define XFS_BUF_SET_BDSTRAT_FUNC(buf, func) \398398- (buf)->pb_strat = (func)399399-#define XFS_BUF_CLR_BDSTRAT_FUNC(buf) \400400- (buf)->pb_strat = NULL304304+#define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone)305305+#define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func))306306+#define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL)307307+#define XFS_BUF_SET_BDSTRAT_FUNC(bp, func) ((bp)->b_strat = (func))308308+#define XFS_BUF_CLR_BDSTRAT_FUNC(bp) ((bp)->b_strat = NULL)401309402402-#define XFS_BUF_FSPRIVATE(buf, type) \403403- ((type)(buf)->pb_fspriv)404404-#define XFS_BUF_SET_FSPRIVATE(buf, value) \405405- (buf)->pb_fspriv = (void *)(value)406406-#define XFS_BUF_FSPRIVATE2(buf, type) \407407- ((type)(buf)->pb_fspriv2)408408-#define XFS_BUF_SET_FSPRIVATE2(buf, value) \409409- (buf)->pb_fspriv2 = (void *)(value)410410-#define XFS_BUF_FSPRIVATE3(buf, type) \411411- ((type)(buf)->pb_fspriv3)412412-#define XFS_BUF_SET_FSPRIVATE3(buf, value) \413413- (buf)->pb_fspriv3 = (void *)(value)414414-#define XFS_BUF_SET_START(buf)310310+#define XFS_BUF_FSPRIVATE(bp, type) ((type)(bp)->b_fspriv)311311+#define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val))312312+#define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2)313313+#define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val))314314+#define XFS_BUF_FSPRIVATE3(bp, type) ((type)(bp)->b_fspriv3)315315+#define XFS_BUF_SET_FSPRIVATE3(bp, val) ((bp)->b_fspriv3 = (void*)(val))316316+#define XFS_BUF_SET_START(bp) do { } while (0)317317+#define XFS_BUF_SET_BRELSE_FUNC(bp, func) ((bp)->b_relse = (func))415318416416-#define XFS_BUF_SET_BRELSE_FUNC(buf, value) \417417- (buf)->pb_relse = (value)319319+#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_addr)320320+#define XFS_BUF_SET_PTR(bp, val, cnt) xfs_buf_associate_memory(bp, val, cnt)321321+#define XFS_BUF_ADDR(bp) ((bp)->b_bn)322322+#define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno))323323+#define XFS_BUF_OFFSET(bp) ((bp)->b_file_offset)324324+#define XFS_BUF_SET_OFFSET(bp, off) ((bp)->b_file_offset = (off))325325+#define XFS_BUF_COUNT(bp) ((bp)->b_count_desired)326326+#define XFS_BUF_SET_COUNT(bp, cnt) ((bp)->b_count_desired = (cnt))327327+#define XFS_BUF_SIZE(bp) ((bp)->b_buffer_length)328328+#define XFS_BUF_SET_SIZE(bp, cnt) ((bp)->b_buffer_length = (cnt))418329419419-#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->pb_addr)330330+#define XFS_BUF_SET_VTYPE_REF(bp, type, ref) do { } while (0)331331+#define XFS_BUF_SET_VTYPE(bp, type) do { } while (0)332332+#define XFS_BUF_SET_REF(bp, ref) do { } while (0)420333421421-static inline xfs_caddr_t xfs_buf_offset(xfs_buf_t *bp, size_t offset)334334+#define XFS_BUF_ISPINNED(bp) xfs_buf_ispin(bp)335335+336336+#define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp)337337+#define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0)338338+#define XFS_BUF_VSEMA(bp) xfs_buf_unlock(bp)339339+#define XFS_BUF_PSEMA(bp,x) xfs_buf_lock(bp)340340+#define XFS_BUF_V_IODONESEMA(bp) up(&bp->b_iodonesema);341341+342342+#define XFS_BUF_SET_TARGET(bp, target) ((bp)->b_target = (target))343343+#define XFS_BUF_TARGET(bp) ((bp)->b_target)344344+#define XFS_BUFTARG_NAME(target) xfs_buf_target_name(target)345345+346346+static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)422347{423423- if (bp->pb_flags & PBF_MAPPED)424424- return XFS_BUF_PTR(bp) + offset;425425- return (xfs_caddr_t) pagebuf_offset(bp, offset);348348+ bp->b_fspriv3 = mp;349349+ bp->b_strat = xfs_bdstrat_cb;350350+ xfs_buf_delwri_dequeue(bp);351351+ return xfs_buf_iostart(bp, XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES);426352}427353428428-#define XFS_BUF_SET_PTR(bp, val, count) \429429- pagebuf_associate_memory(bp, val, count)430430-#define XFS_BUF_ADDR(bp) ((bp)->pb_bn)431431-#define XFS_BUF_SET_ADDR(bp, blk) \432432- ((bp)->pb_bn = (xfs_daddr_t)(blk))433433-#define XFS_BUF_OFFSET(bp) ((bp)->pb_file_offset)434434-#define XFS_BUF_SET_OFFSET(bp, off) \435435- ((bp)->pb_file_offset = (off))436436-#define XFS_BUF_COUNT(bp) ((bp)->pb_count_desired)437437-#define XFS_BUF_SET_COUNT(bp, cnt) \438438- ((bp)->pb_count_desired = (cnt))439439-#define XFS_BUF_SIZE(bp) ((bp)->pb_buffer_length)440440-#define XFS_BUF_SET_SIZE(bp, cnt) \441441- ((bp)->pb_buffer_length = (cnt))442442-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)443443-#define XFS_BUF_SET_VTYPE(bp, type)444444-#define XFS_BUF_SET_REF(bp, ref)445445-446446-#define XFS_BUF_ISPINNED(bp) pagebuf_ispin(bp)447447-448448-#define XFS_BUF_VALUSEMA(bp) pagebuf_lock_value(bp)449449-#define XFS_BUF_CPSEMA(bp) (pagebuf_cond_lock(bp) == 0)450450-#define XFS_BUF_VSEMA(bp) pagebuf_unlock(bp)451451-#define XFS_BUF_PSEMA(bp,x) pagebuf_lock(bp)452452-#define XFS_BUF_V_IODONESEMA(bp) up(&bp->pb_iodonesema);453453-454454-/* setup the buffer target from a buftarg structure */455455-#define XFS_BUF_SET_TARGET(bp, target) \456456- (bp)->pb_target = (target)457457-#define XFS_BUF_TARGET(bp) ((bp)->pb_target)458458-#define XFS_BUFTARG_NAME(target) \459459- pagebuf_target_name(target)460460-461461-#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)462462-#define XFS_BUF_SET_VTYPE(bp, type)463463-#define XFS_BUF_SET_REF(bp, ref)464464-465465-static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)354354+static inline void xfs_buf_relse(xfs_buf_t *bp)466355{467467- bp->pb_fspriv3 = mp;468468- bp->pb_strat = xfs_bdstrat_cb;469469- pagebuf_delwri_dequeue(bp);470470- return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | _PBF_RUN_QUEUES);356356+ if (!bp->b_relse)357357+ xfs_buf_unlock(bp);358358+ xfs_buf_rele(bp);471359}472360473473-static inline void xfs_buf_relse(xfs_buf_t *bp)474474-{475475- if (!bp->pb_relse)476476- pagebuf_unlock(bp);477477- pagebuf_rele(bp);478478-}479479-480480-#define xfs_bpin(bp) pagebuf_pin(bp)481481-#define xfs_bunpin(bp) pagebuf_unpin(bp)361361+#define xfs_bpin(bp) xfs_buf_pin(bp)362362+#define xfs_bunpin(bp) xfs_buf_unpin(bp)482363483364#define xfs_buftrace(id, bp) \484484- pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0))365365+ xfs_buf_trace(bp, id, NULL, (void *)__builtin_return_address(0))485366486486-#define xfs_biodone(pb) \487487- pagebuf_iodone(pb, 0)367367+#define xfs_biodone(bp) xfs_buf_ioend(bp, 0)488368489489-#define xfs_biomove(pb, off, len, data, rw) \490490- pagebuf_iomove((pb), (off), (len), (data), \491491- ((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ)369369+#define xfs_biomove(bp, off, len, data, rw) \370370+ xfs_buf_iomove((bp), (off), (len), (data), \371371+ ((rw) == XFS_B_WRITE) ? XBRW_WRITE : XBRW_READ)492372493493-#define xfs_biozero(pb, off, len) \494494- pagebuf_iomove((pb), (off), (len), NULL, PBRW_ZERO)373373+#define xfs_biozero(bp, off, len) \374374+ xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)495375496376497497-static inline int XFS_bwrite(xfs_buf_t *pb)377377+static inline int XFS_bwrite(xfs_buf_t *bp)498378{499499- int iowait = (pb->pb_flags & PBF_ASYNC) == 0;379379+ int iowait = (bp->b_flags & XBF_ASYNC) == 0;500380 int error = 0;501381502382 if (!iowait)503503- pb->pb_flags |= _PBF_RUN_QUEUES;383383+ bp->b_flags |= _XBF_RUN_QUEUES;504384505505- pagebuf_delwri_dequeue(pb);506506- pagebuf_iostrategy(pb);385385+ xfs_buf_delwri_dequeue(bp);386386+ xfs_buf_iostrategy(bp);507387 if (iowait) {508508- error = pagebuf_iowait(pb);509509- xfs_buf_relse(pb);388388+ error = xfs_buf_iowait(bp);389389+ xfs_buf_relse(bp);510390 }511391 return error;512392}513393514514-#define XFS_bdwrite(pb) \515515- pagebuf_iostart(pb, PBF_DELWRI | PBF_ASYNC)394394+#define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC)516395517396static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)518397{519519- bp->pb_strat = xfs_bdstrat_cb;520520- bp->pb_fspriv3 = mp;521521-522522- return pagebuf_iostart(bp, PBF_DELWRI | PBF_ASYNC);398398+ bp->b_strat = xfs_bdstrat_cb;399399+ bp->b_fspriv3 = mp;400400+ return xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC);523401}524402525525-#define XFS_bdstrat(bp) pagebuf_iorequest(bp)403403+#define XFS_bdstrat(bp) xfs_buf_iorequest(bp)526404527527-#define xfs_iowait(pb) pagebuf_iowait(pb)405405+#define xfs_iowait(bp) xfs_buf_iowait(bp)528406529407#define xfs_baread(target, rablkno, ralen) \530530- pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)531531-532532-#define xfs_buf_get_empty(len, target) pagebuf_get_empty((len), (target))533533-#define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target))534534-#define xfs_buf_free(bp) pagebuf_free(bp)408408+ xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK)535409536410537411/*538412 * Handling of buftargs.539413 */540540-541414extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);542415extern void xfs_free_buftarg(xfs_buftarg_t *, int);543416extern void xfs_wait_buftarg(xfs_buftarg_t *);544417extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);545418extern int xfs_flush_buftarg(xfs_buftarg_t *, int);546419547547-#define xfs_getsize_buftarg(buftarg) \548548- block_size((buftarg)->pbr_bdev)549549-#define xfs_readonly_buftarg(buftarg) \550550- bdev_read_only((buftarg)->pbr_bdev)551551-#define xfs_binval(buftarg) \552552- xfs_flush_buftarg(buftarg, 1)553553-#define XFS_bflush(buftarg) \554554- xfs_flush_buftarg(buftarg, 1)420420+#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)421421+#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)422422+423423+#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1)424424+#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1)555425556426#endif /* __XFS_BUF_H__ */
+2-4
fs/xfs/linux-2.6/xfs_file.c
···509509 vnode_t *vp = LINVFS_GET_VP(inode);510510 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);511511 int error = 0;512512- bhv_desc_t *bdp;513512 xfs_inode_t *ip;514513515514 if (vp->v_vfsp->vfs_flag & VFS_DMI) {516516- bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);517517- if (!bdp) {515515+ ip = xfs_vtoi(vp);516516+ if (!ip) {518517 error = -EINVAL;519518 goto open_exec_out;520519 }521521- ip = XFS_BHVTOI(bdp);522520 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) {523521 error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,524522 0, 0, 0, NULL);
+3-7
fs/xfs/linux-2.6/xfs_ioctl.c
···146146147147 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {148148 xfs_inode_t *ip;149149- bhv_desc_t *bhv;150149 int lock_mode;151150152151 /* need to get access to the xfs_inode to read the generation */153153- bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);154154- ASSERT(bhv);155155- ip = XFS_BHVTOI(bhv);152152+ ip = xfs_vtoi(vp);156153 ASSERT(ip);157154 lock_mode = xfs_ilock_map_shared(ip);158155···748751 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?749752 mp->m_rtdev_targp : mp->m_ddev_targp;750753751751- da.d_mem = da.d_miniosz = 1 << target->pbr_sshift;752752- /* The size dio will do in one go */753753- da.d_maxiosz = 64 * PAGE_CACHE_SIZE;754754+ da.d_mem = da.d_miniosz = 1 << target->bt_sshift;755755+ da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);754756755757 if (copy_to_user(arg, &da, sizeof(da)))756758 return -XFS_ERROR(EFAULT);
+81-40
fs/xfs/linux-2.6/xfs_iops.c
···5454#include <linux/capability.h>5555#include <linux/xattr.h>5656#include <linux/namei.h>5757+#include <linux/security.h>57585859#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \5960 (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))6161+6262+/*6363+ * Get a XFS inode from a given vnode.6464+ */6565+xfs_inode_t *6666+xfs_vtoi(6767+ struct vnode *vp)6868+{6969+ bhv_desc_t *bdp;7070+7171+ bdp = bhv_lookup_range(VN_BHV_HEAD(vp),7272+ VNODE_POSITION_XFS, VNODE_POSITION_XFS);7373+ if (unlikely(bdp == NULL))7474+ return NULL;7575+ return XFS_BHVTOI(bdp);7676+}7777+7878+/*7979+ * Bring the atime in the XFS inode uptodate.8080+ * Used before logging the inode to disk or when the Linux inode goes away.8181+ */8282+void8383+xfs_synchronize_atime(8484+ xfs_inode_t *ip)8585+{8686+ vnode_t *vp;8787+8888+ vp = XFS_ITOV_NULL(ip);8989+ if (vp) {9090+ struct inode *inode = &vp->v_inode;9191+ ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;9292+ ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;9393+ }9494+}60956196/*6297 * Change the requested timestamp in the given inode.···11176{11277 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));11378 timespec_t tv;114114-115115- /*116116- * We're not supposed to change timestamps in readonly-mounted117117- * filesystems. Throw it away if anyone asks us.118118- */119119- if (unlikely(IS_RDONLY(inode)))120120- return;121121-122122- /*123123- * Don't update access timestamps on reads if mounted "noatime".124124- * Throw it away if anyone asks us.125125- */126126- if (unlikely(127127- (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&128128- (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==129129- XFS_ICHGTIME_ACC))130130- return;1317913280 nanotime(&tv);13381 if (flags & XFS_ICHGTIME_MOD) {···148130 * Variant on the above which avoids querying the system clock149131 * in situations where we know the Linux inode timestamps have150132 * just been updated (and so we can update our inode cheaply).151151- * We also skip the readonly and noatime checks here, they are152152- * also catered for already.153133 */154134void155135xfs_ichgtime_fast(···158142 timespec_t *tvp;159143160144 /*145145+ * Atime updates for read() & friends are handled lazily now, and146146+ * explicit updates must go through xfs_ichgtime()147147+ */148148+ ASSERT((flags & XFS_ICHGTIME_ACC) == 0);149149+150150+ /*161151 * We're not supposed to change timestamps in readonly-mounted162152 * filesystems. Throw it away if anyone asks us.163153 */164154 if (unlikely(IS_RDONLY(inode)))165155 return;166156167167- /*168168- * Don't update access timestamps on reads if mounted "noatime".169169- * Throw it away if anyone asks us.170170- */171171- if (unlikely(172172- (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&173173- ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==174174- XFS_ICHGTIME_ACC)))175175- return;176176-177157 if (flags & XFS_ICHGTIME_MOD) {178158 tvp = &inode->i_mtime;179159 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;180160 ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;181181- }182182- if (flags & XFS_ICHGTIME_ACC) {183183- tvp = &inode->i_atime;184184- ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;185185- ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;186161 }187162 if (flags & XFS_ICHGTIME_CHG) {188163 tvp = &inode->i_ctime;···218211 if (i_size_read(ip) != va.va_size)219212 i_size_write(ip, va.va_size);220213 }214214+}215215+216216+/*217217+ * Hook in SELinux. This is not quite correct yet, what we really need218218+ * here (as we do for default ACLs) is a mechanism by which creation of219219+ * these attrs can be journalled at inode creation time (along with the220220+ * inode, of course, such that log replay can't cause these to be lost).221221+ */222222+STATIC int223223+linvfs_init_security(224224+ struct vnode *vp,225225+ struct inode *dir)226226+{227227+ struct inode *ip = LINVFS_GET_IP(vp);228228+ size_t length;229229+ void *value;230230+ char *name;231231+ int error;232232+233233+ error = security_inode_init_security(ip, dir, &name, &value, &length);234234+ if (error) {235235+ if (error == -EOPNOTSUPP)236236+ return 0;237237+ return -error;238238+ }239239+240240+ VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);241241+ if (!error)242242+ VMODIFY(vp);243243+244244+ kfree(name);245245+ kfree(value);246246+ return error;221247}222248223249/*···318278 break;319279 }320280281281+ if (!error)282282+ error = linvfs_init_security(vp, dir);283283+321284 if (default_acl) {322285 if (!error) {323286 error = _ACL_INHERIT(vp, &va, default_acl);···337294 teardown.d_inode = ip = LINVFS_GET_IP(vp);338295 teardown.d_name = dentry->d_name;339296340340- vn_mark_bad(vp);341341-342297 if (S_ISDIR(mode))343298 VOP_RMDIR(dvp, &teardown, NULL, err2);344299 else···547506 ASSERT(dentry);548507 ASSERT(nd);549508550550- link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);509509+ link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL);551510 if (!link) {552511 nd_set_link(nd, ERR_PTR(-ENOMEM));553512 return NULL;···563522 vp = LINVFS_GET_VP(dentry->d_inode);564523565524 iov.iov_base = link;566566- iov.iov_len = MAXNAMELEN;525525+ iov.iov_len = MAXPATHLEN;567526568527 uio->uio_iov = &iov;569528 uio->uio_offset = 0;570529 uio->uio_segflg = UIO_SYSSPACE;571571- uio->uio_resid = MAXNAMELEN;530530+ uio->uio_resid = MAXPATHLEN;572531 uio->uio_iovcnt = 1;573532574533 VOP_READLINK(vp, uio, 0, NULL, error);···576535 kfree(link);577536 link = ERR_PTR(-error);578537 } else {579579- link[MAXNAMELEN - uio->uio_resid] = '\0';538538+ link[MAXPATHLEN - uio->uio_resid] = '\0';580539 }581540 kfree(uio);582541
···128128 return (offset >= minforkoff) ? minforkoff : 0;129129 }130130131131- if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {131131+ if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {132132 if (bytes <= XFS_IFORK_ASIZE(dp))133133 return mp->m_attroffset >> 3;134134 return 0;···157157{158158 unsigned long s;159159160160- if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&160160+ if ((mp->m_flags & XFS_MOUNT_ATTR2) &&161161 !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {162162 s = XFS_SB_LOCK(mp);163163 if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {···311311 */312312 totsize -= size;313313 if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&314314- !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {314314+ (mp->m_flags & XFS_MOUNT_ATTR2)) {315315 /*316316 * Last attribute now removed, revert to original317317 * inode format making all literal area available···330330 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);331331 ASSERT(dp->i_d.di_forkoff);332332 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||333333- (mp->m_flags & XFS_MOUNT_COMPAT_ATTR));333333+ !(mp->m_flags & XFS_MOUNT_ATTR2));334334 dp->i_afp->if_ext_max =335335 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);336336 dp->i_df.if_ext_max =···739739 + name_loc->namelen740740 + INT_GET(name_loc->valuelen, ARCH_CONVERT);741741 }742742- if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) &&742742+ if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&743743 (bytes == sizeof(struct xfs_attr_sf_hdr)))744744 return(-1);745745 return(xfs_attr_shortform_bytesfit(dp, bytes));···778778 goto out;779779780780 if (forkoff == -1) {781781- ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR));781781+ ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);782782783783 /*784784 * Last attribute was removed, revert to original
+43-36
fs/xfs/xfs_attr_leaf.h
···6363 * the leaf_entry. The namespaces are independent only because we also look6464 * at the namespace bit when we are looking for a matching attribute name.6565 *6666- * We also store a "incomplete" bit in the leaf_entry. It shows that an6666+ * We also store an "incomplete" bit in the leaf_entry. It shows that an6767 * attribute is in the middle of being created and should not be shown to6868 * the user if we crash during the time that the bit is set. We clear the6969 * bit when we have finished setting up the attribute. We do this because···7272 */7373#define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */74747575+typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */7676+ __uint16_t base; /* base of free region */7777+ __uint16_t size; /* length of free region */7878+} xfs_attr_leaf_map_t;7979+8080+typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */8181+ xfs_da_blkinfo_t info; /* block type, links, etc. */8282+ __uint16_t count; /* count of active leaf_entry's */8383+ __uint16_t usedbytes; /* num bytes of names/values stored */8484+ __uint16_t firstused; /* first used byte in name area */8585+ __uint8_t holes; /* != 0 if blk needs compaction */8686+ __uint8_t pad1;8787+ xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE];8888+ /* N largest free regions */8989+} xfs_attr_leaf_hdr_t;9090+9191+typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */9292+ xfs_dahash_t hashval; /* hash value of name */9393+ __uint16_t nameidx; /* index into buffer of name/value */9494+ __uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */9595+ __uint8_t pad2; /* unused pad byte */9696+} xfs_attr_leaf_entry_t;9797+9898+typedef struct xfs_attr_leaf_name_local {9999+ __uint16_t valuelen; /* number of bytes in value */100100+ __uint8_t namelen; /* length of name bytes */101101+ __uint8_t nameval[1]; /* name/value bytes */102102+} xfs_attr_leaf_name_local_t;103103+104104+typedef struct xfs_attr_leaf_name_remote {105105+ xfs_dablk_t valueblk; /* block number of value bytes */106106+ __uint32_t valuelen; /* number of bytes in value */107107+ __uint8_t namelen; /* length of name bytes */108108+ __uint8_t name[1]; /* name bytes */109109+} xfs_attr_leaf_name_remote_t;110110+75111typedef struct xfs_attr_leafblock {7676- struct xfs_attr_leaf_hdr { /* constant-structure header block */7777- xfs_da_blkinfo_t info; /* block type, links, etc. */7878- __uint16_t count; /* count of active leaf_entry's */7979- __uint16_t usedbytes; /* num bytes of names/values stored */8080- __uint16_t firstused; /* first used byte in name area */8181- __uint8_t holes; /* != 0 if blk needs compaction */8282- __uint8_t pad1;8383- struct xfs_attr_leaf_map { /* RLE map of free bytes */8484- __uint16_t base; /* base of free region */8585- __uint16_t size; /* length of free region */8686- } freemap[XFS_ATTR_LEAF_MAPSIZE]; /* N largest free regions */8787- } hdr;8888- struct xfs_attr_leaf_entry { /* sorted on key, not name */8989- xfs_dahash_t hashval; /* hash value of name */9090- __uint16_t nameidx; /* index into buffer of name/value */9191- __uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */9292- __uint8_t pad2; /* unused pad byte */9393- } entries[1]; /* variable sized array */9494- struct xfs_attr_leaf_name_local {9595- __uint16_t valuelen; /* number of bytes in value */9696- __uint8_t namelen; /* length of name bytes */9797- __uint8_t nameval[1]; /* name/value bytes */9898- } namelist; /* grows from bottom of buf */9999- struct xfs_attr_leaf_name_remote {100100- xfs_dablk_t valueblk; /* block number of value bytes */101101- __uint32_t valuelen; /* number of bytes in value */102102- __uint8_t namelen; /* length of name bytes */103103- __uint8_t name[1]; /* name bytes */104104- } valuelist; /* grows from bottom of buf */112112+ xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */113113+ xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */114114+ xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */115115+ xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */105116} xfs_attr_leafblock_t;106106-typedef struct xfs_attr_leaf_hdr xfs_attr_leaf_hdr_t;107107-typedef struct xfs_attr_leaf_map xfs_attr_leaf_map_t;108108-typedef struct xfs_attr_leaf_entry xfs_attr_leaf_entry_t;109109-typedef struct xfs_attr_leaf_name_local xfs_attr_leaf_name_local_t;110110-typedef struct xfs_attr_leaf_name_remote xfs_attr_leaf_name_remote_t;111117112118/*113119 * Flags used in the leaf_entry[i].flags field.···156150 (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];157151}158152159159-#define XFS_ATTR_LEAF_NAME(leafp,idx) xfs_attr_leaf_name(leafp,idx)153153+#define XFS_ATTR_LEAF_NAME(leafp,idx) \154154+ xfs_attr_leaf_name(leafp,idx)160155static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)161156{162157 return (&((char *)
+250-160
fs/xfs/xfs_bmap.c
···21462146 return 0; /* keep gcc quite */21472147}2148214821492149+/*21502150+ * Adjust the size of the new extent based on di_extsize and rt extsize.21512151+ */21522152+STATIC int21532153+xfs_bmap_extsize_align(21542154+ xfs_mount_t *mp,21552155+ xfs_bmbt_irec_t *gotp, /* next extent pointer */21562156+ xfs_bmbt_irec_t *prevp, /* previous extent pointer */21572157+ xfs_extlen_t extsz, /* align to this extent size */21582158+ int rt, /* is this a realtime inode? */21592159+ int eof, /* is extent at end-of-file? */21602160+ int delay, /* creating delalloc extent? */21612161+ int convert, /* overwriting unwritten extent? */21622162+ xfs_fileoff_t *offp, /* in/out: aligned offset */21632163+ xfs_extlen_t *lenp) /* in/out: aligned length */21642164+{21652165+ xfs_fileoff_t orig_off; /* original offset */21662166+ xfs_extlen_t orig_alen; /* original length */21672167+ xfs_fileoff_t orig_end; /* original off+len */21682168+ xfs_fileoff_t nexto; /* next file offset */21692169+ xfs_fileoff_t prevo; /* previous file offset */21702170+ xfs_fileoff_t align_off; /* temp for offset */21712171+ xfs_extlen_t align_alen; /* temp for length */21722172+ xfs_extlen_t temp; /* temp for calculations */21732173+21742174+ if (convert)21752175+ return 0;21762176+21772177+ orig_off = align_off = *offp;21782178+ orig_alen = align_alen = *lenp;21792179+ orig_end = orig_off + orig_alen;21802180+21812181+ /*21822182+ * If this request overlaps an existing extent, then don't21832183+ * attempt to perform any additional alignment.21842184+ */21852185+ if (!delay && !eof &&21862186+ (orig_off >= gotp->br_startoff) &&21872187+ (orig_end <= gotp->br_startoff + gotp->br_blockcount)) {21882188+ return 0;21892189+ }21902190+21912191+ /*21922192+ * If the file offset is unaligned vs. the extent size21932193+ * we need to align it. This will be possible unless21942194+ * the file was previously written with a kernel that didn't21952195+ * perform this alignment, or if a truncate shot us in the21962196+ * foot.21972197+ */21982198+ temp = do_mod(orig_off, extsz);21992199+ if (temp) {22002200+ align_alen += temp;22012201+ align_off -= temp;22022202+ }22032203+ /*22042204+ * Same adjustment for the end of the requested area.22052205+ */22062206+ if ((temp = (align_alen % extsz))) {22072207+ align_alen += extsz - temp;22082208+ }22092209+ /*22102210+ * If the previous block overlaps with this proposed allocation22112211+ * then move the start forward without adjusting the length.22122212+ */22132213+ if (prevp->br_startoff != NULLFILEOFF) {22142214+ if (prevp->br_startblock == HOLESTARTBLOCK)22152215+ prevo = prevp->br_startoff;22162216+ else22172217+ prevo = prevp->br_startoff + prevp->br_blockcount;22182218+ } else22192219+ prevo = 0;22202220+ if (align_off != orig_off && align_off < prevo)22212221+ align_off = prevo;22222222+ /*22232223+ * If the next block overlaps with this proposed allocation22242224+ * then move the start back without adjusting the length,22252225+ * but not before offset 0.22262226+ * This may of course make the start overlap previous block,22272227+ * and if we hit the offset 0 limit then the next block22282228+ * can still overlap too.22292229+ */22302230+ if (!eof && gotp->br_startoff != NULLFILEOFF) {22312231+ if ((delay && gotp->br_startblock == HOLESTARTBLOCK) ||22322232+ (!delay && gotp->br_startblock == DELAYSTARTBLOCK))22332233+ nexto = gotp->br_startoff + gotp->br_blockcount;22342234+ else22352235+ nexto = gotp->br_startoff;22362236+ } else22372237+ nexto = NULLFILEOFF;22382238+ if (!eof &&22392239+ align_off + align_alen != orig_end &&22402240+ align_off + align_alen > nexto)22412241+ align_off = nexto > align_alen ? nexto - align_alen : 0;22422242+ /*22432243+ * If we're now overlapping the next or previous extent that22442244+ * means we can't fit an extsz piece in this hole. Just move22452245+ * the start forward to the first valid spot and set22462246+ * the length so we hit the end.22472247+ */22482248+ if (align_off != orig_off && align_off < prevo)22492249+ align_off = prevo;22502250+ if (align_off + align_alen != orig_end &&22512251+ align_off + align_alen > nexto &&22522252+ nexto != NULLFILEOFF) {22532253+ ASSERT(nexto > prevo);22542254+ align_alen = nexto - align_off;22552255+ }22562256+22572257+ /*22582258+ * If realtime, and the result isn't a multiple of the realtime22592259+ * extent size we need to remove blocks until it is.22602260+ */22612261+ if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {22622262+ /*22632263+ * We're not covering the original request, or22642264+ * we won't be able to once we fix the length.22652265+ */22662266+ if (orig_off < align_off ||22672267+ orig_end > align_off + align_alen ||22682268+ align_alen - temp < orig_alen)22692269+ return XFS_ERROR(EINVAL);22702270+ /*22712271+ * Try to fix it by moving the start up.22722272+ */22732273+ if (align_off + temp <= orig_off) {22742274+ align_alen -= temp;22752275+ align_off += temp;22762276+ }22772277+ /*22782278+ * Try to fix it by moving the end in.22792279+ */22802280+ else if (align_off + align_alen - temp >= orig_end)22812281+ align_alen -= temp;22822282+ /*22832283+ * Set the start to the minimum then trim the length.22842284+ */22852285+ else {22862286+ align_alen -= orig_off - align_off;22872287+ align_off = orig_off;22882288+ align_alen -= align_alen % mp->m_sb.sb_rextsize;22892289+ }22902290+ /*22912291+ * Result doesn't cover the request, fail it.22922292+ */22932293+ if (orig_off < align_off || orig_end > align_off + align_alen)22942294+ return XFS_ERROR(EINVAL);22952295+ } else {22962296+ ASSERT(orig_off >= align_off);22972297+ ASSERT(orig_end <= align_off + align_alen);22982298+ }22992299+23002300+#ifdef DEBUG23012301+ if (!eof && gotp->br_startoff != NULLFILEOFF)23022302+ ASSERT(align_off + align_alen <= gotp->br_startoff);23032303+ if (prevp->br_startoff != NULLFILEOFF)23042304+ ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount);23052305+#endif23062306+23072307+ *lenp = align_alen;23082308+ *offp = align_off;23092309+ return 0;23102310+}23112311+21492312#define XFS_ALLOC_GAP_UNITS 42150231321512314/*21522315 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.21532316 * It figures out where to ask the underlying allocator to put the new extent.21542317 */21552155-STATIC int /* error */23182318+STATIC int21562319xfs_bmap_alloc(21572320 xfs_bmalloca_t *ap) /* bmap alloc argument struct */21582321{···23262163 xfs_mount_t *mp; /* mount point structure */23272164 int nullfb; /* true if ap->firstblock isn't set */23282165 int rt; /* true if inode is realtime */23292329-#ifdef __KERNEL__23302330- xfs_extlen_t prod=0; /* product factor for allocators */23312331- xfs_extlen_t ralen=0; /* realtime allocation length */23322332-#endif21662166+ xfs_extlen_t prod = 0; /* product factor for allocators */21672167+ xfs_extlen_t ralen = 0; /* realtime allocation length */21682168+ xfs_extlen_t align; /* minimum allocation alignment */21692169+ xfs_rtblock_t rtx;2333217023342171#define ISVALID(x,y) \23352172 (rt ? \···23452182 nullfb = ap->firstblock == NULLFSBLOCK;23462183 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;23472184 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);23482348-#ifdef __KERNEL__23492185 if (rt) {23502350- xfs_extlen_t extsz; /* file extent size for rt */23512351- xfs_fileoff_t nexto; /* next file offset */23522352- xfs_extlen_t orig_alen; /* original ap->alen */23532353- xfs_fileoff_t orig_end; /* original off+len */23542354- xfs_fileoff_t orig_off; /* original ap->off */23552355- xfs_extlen_t mod_off; /* modulus calculations */23562356- xfs_fileoff_t prevo; /* previous file offset */23572357- xfs_rtblock_t rtx; /* realtime extent number */23582358- xfs_extlen_t temp; /* temp for rt calculations */21862186+ align = ap->ip->i_d.di_extsize ?21872187+ ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;21882188+ /* Set prod to match the extent size */21892189+ prod = align / mp->m_sb.sb_rextsize;2359219023602360- /*23612361- * Set prod to match the realtime extent size.23622362- */23632363- if (!(extsz = ap->ip->i_d.di_extsize))23642364- extsz = mp->m_sb.sb_rextsize;23652365- prod = extsz / mp->m_sb.sb_rextsize;23662366- orig_off = ap->off;23672367- orig_alen = ap->alen;23682368- orig_end = orig_off + orig_alen;23692369- /*23702370- * If the file offset is unaligned vs. the extent size23712371- * we need to align it. This will be possible unless23722372- * the file was previously written with a kernel that didn't23732373- * perform this alignment.23742374- */23752375- mod_off = do_mod(orig_off, extsz);23762376- if (mod_off) {23772377- ap->alen += mod_off;23782378- ap->off -= mod_off;23792379- }23802380- /*23812381- * Same adjustment for the end of the requested area.23822382- */23832383- if ((temp = (ap->alen % extsz)))23842384- ap->alen += extsz - temp;23852385- /*23862386- * If the previous block overlaps with this proposed allocation23872387- * then move the start forward without adjusting the length.23882388- */23892389- prevo =23902390- ap->prevp->br_startoff == NULLFILEOFF ?23912391- 0 :23922392- (ap->prevp->br_startoff +23932393- ap->prevp->br_blockcount);23942394- if (ap->off != orig_off && ap->off < prevo)23952395- ap->off = prevo;23962396- /*23972397- * If the next block overlaps with this proposed allocation23982398- * then move the start back without adjusting the length,23992399- * but not before offset 0.24002400- * This may of course make the start overlap previous block,24012401- * and if we hit the offset 0 limit then the next block24022402- * can still overlap too.24032403- */24042404- nexto = (ap->eof || ap->gotp->br_startoff == NULLFILEOFF) ?24052405- NULLFILEOFF : ap->gotp->br_startoff;24062406- if (!ap->eof &&24072407- ap->off + ap->alen != orig_end &&24082408- ap->off + ap->alen > nexto)24092409- ap->off = nexto > ap->alen ? nexto - ap->alen : 0;24102410- /*24112411- * If we're now overlapping the next or previous extent that24122412- * means we can't fit an extsz piece in this hole. Just move24132413- * the start forward to the first valid spot and set24142414- * the length so we hit the end.24152415- */24162416- if ((ap->off != orig_off && ap->off < prevo) ||24172417- (ap->off + ap->alen != orig_end &&24182418- ap->off + ap->alen > nexto)) {24192419- ap->off = prevo;24202420- ap->alen = nexto - prevo;24212421- }24222422- /*24232423- * If the result isn't a multiple of rtextents we need to24242424- * remove blocks until it is.24252425- */24262426- if ((temp = (ap->alen % mp->m_sb.sb_rextsize))) {24272427- /*24282428- * We're not covering the original request, or24292429- * we won't be able to once we fix the length.24302430- */24312431- if (orig_off < ap->off ||24322432- orig_end > ap->off + ap->alen ||24332433- ap->alen - temp < orig_alen)24342434- return XFS_ERROR(EINVAL);24352435- /*24362436- * Try to fix it by moving the start up.24372437- */24382438- if (ap->off + temp <= orig_off) {24392439- ap->alen -= temp;24402440- ap->off += temp;24412441- }24422442- /*24432443- * Try to fix it by moving the end in.24442444- */24452445- else if (ap->off + ap->alen - temp >= orig_end)24462446- ap->alen -= temp;24472447- /*24482448- * Set the start to the minimum then trim the length.24492449- */24502450- else {24512451- ap->alen -= orig_off - ap->off;24522452- ap->off = orig_off;24532453- ap->alen -= ap->alen % mp->m_sb.sb_rextsize;24542454- }24552455- /*24562456- * Result doesn't cover the request, fail it.24572457- */24582458- if (orig_off < ap->off || orig_end > ap->off + ap->alen)24592459- return XFS_ERROR(EINVAL);24602460- }21912191+ error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,21922192+ align, rt, ap->eof, 0,21932193+ ap->conv, &ap->off, &ap->alen);21942194+ if (error)21952195+ return error;21962196+ ASSERT(ap->alen);24612197 ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);21982198+24622199 /*24632200 * If the offset & length are not perfectly aligned24642201 * then kill prod, it will just get us in trouble.24652202 */24662466- if (do_mod(ap->off, extsz) || ap->alen % extsz)22032203+ if (do_mod(ap->off, align) || ap->alen % align)24672204 prod = 1;24682205 /*24692206 * Set ralen to be the actual requested length in rtextents.···23892326 ap->rval = rtx * mp->m_sb.sb_rextsize;23902327 } else23912328 ap->rval = 0;23292329+ } else {23302330+ align = (ap->userdata && ap->ip->i_d.di_extsize &&23312331+ (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?23322332+ ap->ip->i_d.di_extsize : 0;23332333+ if (unlikely(align)) {23342334+ error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,23352335+ align, rt,23362336+ ap->eof, 0, ap->conv,23372337+ &ap->off, &ap->alen);23382338+ ASSERT(!error);23392339+ ASSERT(ap->alen);23402340+ }23412341+ if (nullfb)23422342+ ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);23432343+ else23442344+ ap->rval = ap->firstblock;23922345 }23932393-#else23942394- if (rt)23952395- ap->rval = 0;23962396-#endif /* __KERNEL__ */23972397- else if (nullfb)23982398- ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);23992399- else24002400- ap->rval = ap->firstblock;23462346+24012347 /*24022348 * If allocating at eof, and there's a previous real block,24032349 * try to use it's last block as our starting point.···26702598 args.total = ap->total;26712599 args.minlen = ap->minlen;26722600 }26732673- if (ap->ip->i_d.di_extsize) {26012601+ if (unlikely(ap->userdata && ap->ip->i_d.di_extsize &&26022602+ (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) {26742603 args.prod = ap->ip->i_d.di_extsize;26752604 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))26762605 args.mod = (xfs_extlen_t)(args.prod - args.mod);26772677- } else if (mp->m_sb.sb_blocksize >= NBPP) {26062606+ } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {26782607 args.prod = 1;26792608 args.mod = 0;26802609 } else {···3653358036543581 ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp,36553582 lastxp, gotp, prevp);36563656- rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME;36573657- if(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM)) {35833583+ rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);35843584+ if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {36583585 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "36593586 "start_block : %llx start_off : %llx blkcnt : %llx "36603587 "extent-state : %x \n",36613661- (ip->i_mount)->m_fsname,(long long)ip->i_ino,36623662- gotp->br_startblock, gotp->br_startoff,36633663- gotp->br_blockcount,gotp->br_state);35883588+ (ip->i_mount)->m_fsname, (long long)ip->i_ino,35893589+ (unsigned long long)gotp->br_startblock,35903590+ (unsigned long long)gotp->br_startoff,35913591+ (unsigned long long)gotp->br_blockcount,35923592+ gotp->br_state);36643593 }36653594 return ep;36663595}···39503875 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);39513876 if (!ip->i_d.di_forkoff)39523877 ip->i_d.di_forkoff = mp->m_attroffset >> 3;39533953- else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))38783878+ else if (mp->m_flags & XFS_MOUNT_ATTR2)39543879 version = 2;39553880 break;39563881 default:···40984023 */40994024 if (whichfork == XFS_DATA_FORK) {41004025 maxleafents = MAXEXTNUM;41014101- sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?41024102- mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);40264026+ sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?40274027+ XFS_BMDR_SPACE_CALC(MINDBTPTRS) : mp->m_attroffset;41034028 } else {41044029 maxleafents = MAXAEXTNUM;41054105- sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?41064106- mp->m_sb.sb_inodesize - mp->m_attroffset :41074107- XFS_BMDR_SPACE_CALC(MINABTPTRS);40304030+ sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?40314031+ XFS_BMDR_SPACE_CALC(MINABTPTRS) :40324032+ mp->m_sb.sb_inodesize - mp->m_attroffset;41084033 }41094034 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);41104035 minleafrecs = mp->m_bmap_dmnr[0];···44934418 num_recs = be16_to_cpu(block->bb_numrecs);44944419 if (unlikely(i + num_recs > room)) {44954420 ASSERT(i + num_recs <= room);44964496- xfs_fs_cmn_err(CE_WARN, ip->i_mount,44974497- "corrupt dinode %Lu, (btree extents). Unmount and run xfs_repair.",44214421+ xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,44224422+ "corrupt dinode %Lu, (btree extents).",44984423 (unsigned long long) ip->i_ino);44994424 XFS_ERROR_REPORT("xfs_bmap_read_extents(1)",45004425 XFS_ERRLEVEL_LOW,···46654590 char contig; /* allocation must be one extent */46664591 char delay; /* this request is for delayed alloc */46674592 char exact; /* don't do all of wasdelayed extent */45934593+ char convert; /* unwritten extent I/O completion */46684594 xfs_bmbt_rec_t *ep; /* extent list entry pointer */46694595 int error; /* error return */46704596 xfs_bmbt_irec_t got; /* current extent list record */···47194643 }47204644 if (XFS_FORCED_SHUTDOWN(mp))47214645 return XFS_ERROR(EIO);47224722- rt = XFS_IS_REALTIME_INODE(ip);46464646+ rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);47234647 ifp = XFS_IFORK_PTR(ip, whichfork);47244648 ASSERT(ifp->if_ext_max ==47254649 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));···47304654 delay = (flags & XFS_BMAPI_DELAY) != 0;47314655 trim = (flags & XFS_BMAPI_ENTIRE) == 0;47324656 userdata = (flags & XFS_BMAPI_METADATA) == 0;46574657+ convert = (flags & XFS_BMAPI_CONVERT) != 0;47334658 exact = (flags & XFS_BMAPI_EXACT) != 0;47344659 rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0;47354660 contig = (flags & XFS_BMAPI_CONTIG) != 0;···48254748 }48264749 minlen = contig ? alen : 1;48274750 if (delay) {48284828- xfs_extlen_t extsz = 0;47514751+ xfs_extlen_t extsz;4829475248304753 /* Figure out the extent size, adjust alen */48314754 if (rt) {48324755 if (!(extsz = ip->i_d.di_extsize))48334756 extsz = mp->m_sb.sb_rextsize;48344834- alen = roundup(alen, extsz);48354835- extsz = alen / mp->m_sb.sb_rextsize;47574757+ } else {47584758+ extsz = ip->i_d.di_extsize;48364759 }47604760+ if (extsz) {47614761+ error = xfs_bmap_extsize_align(mp,47624762+ &got, &prev, extsz,47634763+ rt, eof, delay, convert,47644764+ &aoff, &alen);47654765+ ASSERT(!error);47664766+ }47674767+47684768+ if (rt)47694769+ extsz = alen / mp->m_sb.sb_rextsize;4837477048384771 /*48394772 * Make a transaction-less quota reservation for···48724785 xfs_bmap_worst_indlen(ip, alen);48734786 ASSERT(indlen > 0);4874478748754875- if (rt)47884788+ if (rt) {48764789 error = xfs_mod_incore_sb(mp,48774790 XFS_SBS_FREXTENTS,48784791 -(extsz), rsvd);48794879- else47924792+ } else {48804793 error = xfs_mod_incore_sb(mp,48814794 XFS_SBS_FDBLOCKS,48824795 -(alen), rsvd);47964796+ }48834797 if (!error) {48844798 error = xfs_mod_incore_sb(mp,48854799 XFS_SBS_FDBLOCKS,48864800 -(indlen), rsvd);48874887- if (error && rt) {48884888- xfs_mod_incore_sb(ip->i_mount,48014801+ if (error && rt)48024802+ xfs_mod_incore_sb(mp,48894803 XFS_SBS_FREXTENTS,48904804 extsz, rsvd);48914891- } else if (error) {48924892- xfs_mod_incore_sb(ip->i_mount,48054805+ else if (error)48064806+ xfs_mod_incore_sb(mp,48934807 XFS_SBS_FDBLOCKS,48944808 alen, rsvd);48954895- }48964809 }4897481048984811 if (error) {48994899- if (XFS_IS_QUOTA_ON(ip->i_mount))48124812+ if (XFS_IS_QUOTA_ON(mp))49004813 /* unreserve the blocks now */48144814+ (void)49014815 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(49024816 mp, NULL, ip,49034817 (long)alen, 0, rt ?···49374849 bma.firstblock = *firstblock;49384850 bma.alen = alen;49394851 bma.off = aoff;48524852+ bma.conv = convert;49404853 bma.wasdel = wasdelay;49414854 bma.minlen = minlen;49424855 bma.low = flist->xbf_low;···53595270 return 0;53605271 }53615272 XFS_STATS_INC(xs_blk_unmap);53625362- isrt = (whichfork == XFS_DATA_FORK) &&53635363- (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);52735273+ isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);53645274 start = bno;53655275 bno = start + len - 1;53665276 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,···55315443 }55325444 if (wasdel) {55335445 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);55345534- /* Update realtim/data freespace, unreserve quota */54465446+ /* Update realtime/data freespace, unreserve quota */55355447 if (isrt) {55365448 xfs_filblks_t rtexts;55375449···55395451 do_div(rtexts, mp->m_sb.sb_rextsize);55405452 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,55415453 (int)rtexts, rsvd);55425542- XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,55435543- -((long)del.br_blockcount), 0,54545454+ (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,54555455+ NULL, ip, -((long)del.br_blockcount), 0,55445456 XFS_QMOPT_RES_RTBLKS);55455457 } else {55465458 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,55475459 (int)del.br_blockcount, rsvd);55485548- XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,55495549- -((long)del.br_blockcount), 0,54605460+ (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,54615461+ NULL, ip, -((long)del.br_blockcount), 0,55505462 XFS_QMOPT_RES_REGBLKS);55515463 }55525464 ip->i_delayed_blks -= del.br_blockcount;···57405652 ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)57415653 return XFS_ERROR(EINVAL);57425654 if (whichfork == XFS_DATA_FORK) {57435743- if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {56555655+ if ((ip->i_d.di_extsize && (ip->i_d.di_flags &56565656+ (XFS_DIFLAG_REALTIME|XFS_DIFLAG_EXTSIZE))) ||56575657+ ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){57445658 prealloced = 1;57455659 fixlen = XFS_MAXIOFFSET(mp);57465660 } else {
+6-1
fs/xfs/xfs_bmap.h
···6262#define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */6363 /* combine contig. space */6464#define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */6565+/* XFS_BMAPI_DIRECT_IO 0x800 */6666+#define XFS_BMAPI_CONVERT 0x1000 /* unwritten extent conversion - */6767+ /* need write cache flushing and no */6868+ /* additional allocation alignments */65696670#define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w)6771static inline int xfs_bmapi_aflag(int w)···105101 char wasdel; /* replacing a delayed allocation */106102 char userdata;/* set if is user data */107103 char low; /* low on space, using seq'l ags */108108- char aeof; /* allocated space at eof */104104+ char aeof; /* allocated space at eof */105105+ char conv; /* overwriting unwritten extents */109106} xfs_bmalloca_t;110107111108#ifdef __KERNEL__
+1-1
fs/xfs/xfs_clnt.h
···5757/*5858 * XFS mount option flags -- args->flags15959 */6060-#define XFSMNT_COMPAT_ATTR 0x00000001 /* do not use ATTR2 format */6060+#define XFSMNT_ATTR2 0x00000001 /* allow ATTR2 EA format */6161#define XFSMNT_WSYNC 0x00000002 /* safe mode nfs mount6262 * compatible */6363#define XFSMNT_INO64 0x00000004 /* move inode numbers up
+4-12
fs/xfs/xfs_dfrag.c
···6060 xfs_bstat_t *sbp;6161 struct file *fp = NULL, *tfp = NULL;6262 vnode_t *vp, *tvp;6363- bhv_desc_t *bdp, *tbdp;6464- vn_bhv_head_t *bhp, *tbhp;6563 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;6664 int ilf_fields, tilf_fields;6765 int error = 0;···8890 goto error0;8991 }90929191- bhp = VN_BHV_HEAD(vp);9292- bdp = vn_bhv_lookup(bhp, &xfs_vnodeops);9393- if (bdp == NULL) {9393+ ip = xfs_vtoi(vp);9494+ if (ip == NULL) {9495 error = XFS_ERROR(EBADF);9596 goto error0;9696- } else {9797- ip = XFS_BHVTOI(bdp);9897 }999810099 if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) ||···100105 goto error0;101106 }102107103103- tbhp = VN_BHV_HEAD(tvp);104104- tbdp = vn_bhv_lookup(tbhp, &xfs_vnodeops);105105- if (tbdp == NULL) {108108+ tip = xfs_vtoi(tvp);109109+ if (tip == NULL) {106110 error = XFS_ERROR(EBADF);107111 goto error0;108108- } else {109109- tip = XFS_BHVTOI(tbdp);110112 }111113112114 if (ip->i_mount != tip->i_mount) {
···7272 struct uio *uio; /* uio control structure */7373} xfs_dir2_put_args_t;74747575-#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)7676-extern xfs_dirops_t xfsv2_dirops;7777-7875/*7976 * Other interfaces used by the rest of the dir v2 code.8077 */
+34-30
fs/xfs/xfs_dir_leaf.h
···6767 */6868#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */69697070+typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */7171+ __uint16_t base; /* base of free region */7272+ __uint16_t size; /* run length of free region */7373+} xfs_dir_leaf_map_t;7474+7575+typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */7676+ xfs_da_blkinfo_t info; /* block type, links, etc. */7777+ __uint16_t count; /* count of active leaf_entry's */7878+ __uint16_t namebytes; /* num bytes of name strings stored */7979+ __uint16_t firstused; /* first used byte in name area */8080+ __uint8_t holes; /* != 0 if blk needs compaction */8181+ __uint8_t pad1;8282+ xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];8383+} xfs_dir_leaf_hdr_t;8484+8585+typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */8686+ xfs_dahash_t hashval; /* hash value of name */8787+ __uint16_t nameidx; /* index into buffer of name */8888+ __uint8_t namelen; /* length of name string */8989+ __uint8_t pad2;9090+} xfs_dir_leaf_entry_t;9191+9292+typedef struct xfs_dir_leaf_name {9393+ xfs_dir_ino_t inumber; /* inode number for this key */9494+ __uint8_t name[1]; /* name string itself */9595+} xfs_dir_leaf_name_t;9696+7097typedef struct xfs_dir_leafblock {7171- struct xfs_dir_leaf_hdr { /* constant-structure header block */7272- xfs_da_blkinfo_t info; /* block type, links, etc. */7373- __uint16_t count; /* count of active leaf_entry's */7474- __uint16_t namebytes; /* num bytes of name strings stored */7575- __uint16_t firstused; /* first used byte in name area */7676- __uint8_t holes; /* != 0 if blk needs compaction */7777- __uint8_t pad1;7878- struct xfs_dir_leaf_map {/* RLE map of free bytes */7979- __uint16_t base; /* base of free region */8080- __uint16_t size; /* run length of free region */8181- } freemap[XFS_DIR_LEAF_MAPSIZE]; /* N largest free regions */8282- } hdr;8383- struct xfs_dir_leaf_entry { /* sorted on key, not name */8484- xfs_dahash_t hashval; /* hash value of name */8585- __uint16_t nameidx; /* index into buffer of name */8686- __uint8_t namelen; /* length of name string */8787- __uint8_t pad2;8888- } entries[1]; /* var sized array */8989- struct xfs_dir_leaf_name {9090- xfs_dir_ino_t inumber; /* inode number for this key */9191- __uint8_t name[1]; /* name string itself */9292- } namelist[1]; /* grows from bottom of buf */9898+ xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */9999+ xfs_dir_leaf_entry_t entries[1]; /* var sized array */100100+ xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */93101} xfs_dir_leafblock_t;9494-typedef struct xfs_dir_leaf_hdr xfs_dir_leaf_hdr_t;9595-typedef struct xfs_dir_leaf_map xfs_dir_leaf_map_t;9696-typedef struct xfs_dir_leaf_entry xfs_dir_leaf_entry_t;9797-typedef struct xfs_dir_leaf_name xfs_dir_leaf_name_t;9810299103/*100104 * Length of name for which a 512-byte block filesystem···130126#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \131127 ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))132128133133-typedef struct xfs_dir_put_args134134-{129129+typedef struct xfs_dir_put_args {135130 xfs_dircook_t cook; /* cookie of (next) entry */136131 xfs_intino_t ino; /* inode number */137137- struct xfs_dirent *dbp; /* buffer pointer */132132+ struct xfs_dirent *dbp; /* buffer pointer */138133 char *name; /* directory entry name */139134 int namelen; /* length of name */140135 int done; /* output: set if value was stored */···141138 struct uio *uio; /* uio control structure */142139} xfs_dir_put_args_t;143140144144-#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) xfs_dir_leaf_entsize_byname(len)141141+#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \142142+ xfs_dir_leaf_entsize_byname(len)145143static inline int xfs_dir_leaf_entsize_byname(int len)146144{147145 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
-1
fs/xfs/xfs_error.c
···5454 if (e != xfs_etrap[i])5555 continue;5656 cmn_err(CE_NOTE, "xfs_error_trap: error %d", e);5757- debug_stop_all_cpus((void *)-1LL);5857 BUG();5958 break;6059 }
+4-4
fs/xfs/xfs_error.h
···1818#ifndef __XFS_ERROR_H__1919#define __XFS_ERROR_H__20202121-#define prdev(fmt,targ,args...) \2222- printk("XFS: device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)2323-2421#define XFS_ERECOVER 1 /* Failure to recover log */2522#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */2623#define XFS_ENOLOGSPACE 3 /* Reservation too large */···179182struct xfs_mount;180183/* PRINTFLIKE4 */181184extern void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,182182- char *fmt, ...);185185+ char *fmt, ...);183186/* PRINTFLIKE3 */184187extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);188188+189189+#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \190190+ xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args)185191186192#endif /* __XFS_ERROR_H__ */
+6-4
fs/xfs/xfs_fs.h
···33 * All Rights Reserved.44 *55 * This program is free software; you can redistribute it and/or66- * modify it under the terms of the GNU General Public License as77- * published by the Free Software Foundation.66+ * modify it under the terms of the GNU Lesser General Public License77+ * as published by the Free Software Foundation.88 *99 * This program is distributed in the hope that it would be useful,1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of1111 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1212- * GNU General Public License for more details.1212+ * GNU Lesser General Public License for more details.1313 *1414- * You should have received a copy of the GNU General Public License1414+ * You should have received a copy of the GNU Lesser General Public License1515 * along with this program; if not, write the Free Software Foundation,1616 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA1717 */···6565#define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */6666#define XFS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */6767#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */6868+#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */6969+#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */6870#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */69717072/*
···271271 if (ip->i_update_size)272272 ip->i_update_size = 0;273273274274+ /*275275+ * Make sure to get the latest atime from the Linux inode.276276+ */277277+ xfs_synchronize_atime(ip);278278+274279 vecp->i_addr = (xfs_caddr_t)&ip->i_d;275280 vecp->i_len = sizeof(xfs_dinode_core_t);276281 XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);···608603 if (iip->ili_pushbuf_flag == 0) {609604 iip->ili_pushbuf_flag = 1;610605#ifdef DEBUG611611- iip->ili_push_owner = get_thread_id();606606+ iip->ili_push_owner = current_pid();612607#endif613608 /*614609 * Inode is left locked in shared mode.···787782 * trying to duplicate our effort.788783 */789784 ASSERT(iip->ili_pushbuf_flag != 0);790790- ASSERT(iip->ili_push_owner == get_thread_id());785785+ ASSERT(iip->ili_push_owner == current_pid());791786792787 /*793788 * If flushlock isn't locked anymore, chances are that the
+236-193
fs/xfs/xfs_iomap.c
···262262 case BMAPI_WRITE:263263 /* If we found an extent, return it */264264 if (nimaps &&265265- (imap.br_startblock != HOLESTARTBLOCK) && 265265+ (imap.br_startblock != HOLESTARTBLOCK) &&266266 (imap.br_startblock != DELAYSTARTBLOCK)) {267267 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,268268 offset, count, iomapp, &imap, flags);···317317}318318319319STATIC int320320+xfs_iomap_eof_align_last_fsb(321321+ xfs_mount_t *mp,322322+ xfs_iocore_t *io,323323+ xfs_fsize_t isize,324324+ xfs_extlen_t extsize,325325+ xfs_fileoff_t *last_fsb)326326+{327327+ xfs_fileoff_t new_last_fsb = 0;328328+ xfs_extlen_t align;329329+ int eof, error;330330+331331+ if (io->io_flags & XFS_IOCORE_RT)332332+ ;333333+ /*334334+ * If mounted with the "-o swalloc" option, roundup the allocation335335+ * request to a stripe width boundary if the file size is >=336336+ * stripe width and we are allocating past the allocation eof.337337+ */338338+ else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) &&339339+ (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)))340340+ new_last_fsb = roundup_64(*last_fsb, mp->m_swidth);341341+ /*342342+ * Roundup the allocation request to a stripe unit (m_dalign) boundary343343+ * if the file size is >= stripe unit size, and we are allocating past344344+ * the allocation eof.345345+ */346346+ else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)))347347+ new_last_fsb = roundup_64(*last_fsb, mp->m_dalign);348348+349349+ /*350350+ * Always round up the allocation request to an extent boundary351351+ * (when file on a real-time subvolume or has di_extsize hint).352352+ */353353+ if (extsize) {354354+ if (new_last_fsb)355355+ align = roundup_64(new_last_fsb, extsize);356356+ else357357+ align = extsize;358358+ new_last_fsb = roundup_64(*last_fsb, align);359359+ }360360+361361+ if (new_last_fsb) {362362+ error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);363363+ if (error)364364+ return error;365365+ if (eof)366366+ *last_fsb = new_last_fsb;367367+ }368368+ return 0;369369+}370370+371371+STATIC int320372xfs_flush_space(321373 xfs_inode_t *ip,322374 int *fsynced,···414362 xfs_iocore_t *io = &ip->i_iocore;415363 xfs_fileoff_t offset_fsb;416364 xfs_fileoff_t last_fsb;417417- xfs_filblks_t count_fsb;365365+ xfs_filblks_t count_fsb, resaligned;418366 xfs_fsblock_t firstfsb;367367+ xfs_extlen_t extsz, temp;368368+ xfs_fsize_t isize;419369 int nimaps;420420- int error;421370 int bmapi_flag;422371 int quota_flag;423372 int rt;424373 xfs_trans_t *tp;425374 xfs_bmbt_irec_t imap;426375 xfs_bmap_free_t free_list;427427- xfs_filblks_t qblocks, resblks;376376+ uint qblocks, resblks, resrtextents;428377 int committed;429429- int resrtextents;378378+ int error;430379431380 /*432381 * Make sure that the dquots are there. This doesn't hold···437384 if (error)438385 return XFS_ERROR(error);439386440440- offset_fsb = XFS_B_TO_FSBT(mp, offset);441441- last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));442442- count_fsb = last_fsb - offset_fsb;443443- if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) {444444- xfs_fileoff_t map_last_fsb;445445-446446- map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;447447- if (map_last_fsb < last_fsb) {448448- last_fsb = map_last_fsb;449449- count_fsb = last_fsb - offset_fsb;450450- }451451- ASSERT(count_fsb > 0);452452- }453453-454454- /*455455- * Determine if reserving space on the data or realtime partition.456456- */457457- if ((rt = XFS_IS_REALTIME_INODE(ip))) {458458- xfs_extlen_t extsz;459459-387387+ rt = XFS_IS_REALTIME_INODE(ip);388388+ if (unlikely(rt)) {460389 if (!(extsz = ip->i_d.di_extsize))461390 extsz = mp->m_sb.sb_rextsize;462462- resrtextents = qblocks = (count_fsb + extsz - 1);463463- do_div(resrtextents, mp->m_sb.sb_rextsize);464464- resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);465465- quota_flag = XFS_QMOPT_RES_RTBLKS;466391 } else {467467- resrtextents = 0;468468- resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, count_fsb);469469- quota_flag = XFS_QMOPT_RES_REGBLKS;392392+ extsz = ip->i_d.di_extsize;470393 }394394+395395+ isize = ip->i_d.di_size;396396+ if (io->io_new_size > isize)397397+ isize = io->io_new_size;398398+399399+ offset_fsb = XFS_B_TO_FSBT(mp, offset);400400+ last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));401401+ if ((offset + count) > isize) {402402+ error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,403403+ &last_fsb);404404+ if (error)405405+ goto error_out;406406+ } else {407407+ if (found && (ret_imap->br_startblock == HOLESTARTBLOCK))408408+ last_fsb = MIN(last_fsb, (xfs_fileoff_t)409409+ ret_imap->br_blockcount +410410+ ret_imap->br_startoff);411411+ }412412+ count_fsb = last_fsb - offset_fsb;413413+ ASSERT(count_fsb > 0);414414+415415+ resaligned = count_fsb;416416+ if (unlikely(extsz)) {417417+ if ((temp = do_mod(offset_fsb, extsz)))418418+ resaligned += temp;419419+ if ((temp = do_mod(resaligned, extsz)))420420+ resaligned += extsz - temp;421421+ }422422+423423+ if (unlikely(rt)) {424424+ resrtextents = qblocks = resaligned;425425+ resrtextents /= mp->m_sb.sb_rextsize;426426+ resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);427427+ quota_flag = XFS_QMOPT_RES_RTBLKS;428428+ } else {429429+ resrtextents = 0;430430+ resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);431431+ quota_flag = XFS_QMOPT_RES_REGBLKS;432432+ }471433472434 /*473435 * Allocate and setup the transaction···493425 XFS_WRITE_LOG_RES(mp), resrtextents,494426 XFS_TRANS_PERM_LOG_RES,495427 XFS_WRITE_LOG_COUNT);496496-497428 /*498429 * Check for running out of space, note: need lock to return499430 */···502435 if (error)503436 goto error_out;504437505505- if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {506506- error = (EDQUOT);438438+ error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,439439+ qblocks, 0, quota_flag);440440+ if (error)507441 goto error1;508508- }509442510510- bmapi_flag = XFS_BMAPI_WRITE;511443 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);512444 xfs_trans_ihold(tp, ip);513445514514- if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt))446446+ bmapi_flag = XFS_BMAPI_WRITE;447447+ if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))515448 bmapi_flag |= XFS_BMAPI_PREALLOC;516449517450 /*518518- * Issue the bmapi() call to allocate the blocks451451+ * Issue the xfs_bmapi() call to allocate the blocks519452 */520453 XFS_BMAP_INIT(&free_list, &firstfsb);521454 nimaps = 1;···550483 "extent-state : %x \n",551484 (ip->i_mount)->m_fsname,552485 (long long)ip->i_ino,553553- ret_imap->br_startblock, ret_imap->br_startoff,554554- ret_imap->br_blockcount,ret_imap->br_state);486486+ (unsigned long long)ret_imap->br_startblock,487487+ (unsigned long long)ret_imap->br_startoff,488488+ (unsigned long long)ret_imap->br_blockcount,489489+ ret_imap->br_state);555490 }556491 return 0;557492···569500 return XFS_ERROR(error);570501}571502503503+/*504504+ * If the caller is doing a write at the end of the file,505505+ * then extend the allocation out to the file system's write506506+ * iosize. We clean up any extra space left over when the507507+ * file is closed in xfs_inactive().508508+ *509509+ * For sync writes, we are flushing delayed allocate space to510510+ * try to make additional space available for allocation near511511+ * the filesystem full boundary - preallocation hurts in that512512+ * situation, of course.513513+ */514514+STATIC int515515+xfs_iomap_eof_want_preallocate(516516+ xfs_mount_t *mp,517517+ xfs_iocore_t *io,518518+ xfs_fsize_t isize,519519+ xfs_off_t offset,520520+ size_t count,521521+ int ioflag,522522+ xfs_bmbt_irec_t *imap,523523+ int nimaps,524524+ int *prealloc)525525+{526526+ xfs_fileoff_t start_fsb;527527+ xfs_filblks_t count_fsb;528528+ xfs_fsblock_t firstblock;529529+ int n, error, imaps;530530+531531+ *prealloc = 0;532532+ if ((ioflag & BMAPI_SYNC) || (offset + count) <= isize)533533+ return 0;534534+535535+ /*536536+ * If there are any real blocks past eof, then don't537537+ * do any speculative allocation.538538+ */539539+ start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1)));540540+ count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));541541+ while (count_fsb > 0) {542542+ imaps = nimaps;543543+ firstblock = NULLFSBLOCK;544544+ error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,545545+ 0, &firstblock, 0, imap, &imaps, NULL);546546+ if (error)547547+ return error;548548+ for (n = 0; n < imaps; n++) {549549+ if ((imap[n].br_startblock != HOLESTARTBLOCK) &&550550+ (imap[n].br_startblock != DELAYSTARTBLOCK))551551+ return 0;552552+ start_fsb += imap[n].br_blockcount;553553+ count_fsb -= imap[n].br_blockcount;554554+ }555555+ }556556+ *prealloc = 1;557557+ return 0;558558+}559559+572560int573561xfs_iomap_write_delay(574562 xfs_inode_t *ip,···639513 xfs_iocore_t *io = &ip->i_iocore;640514 xfs_fileoff_t offset_fsb;641515 xfs_fileoff_t last_fsb;642642- xfs_fsize_t isize;516516+ xfs_off_t aligned_offset;517517+ xfs_fileoff_t ioalign;643518 xfs_fsblock_t firstblock;519519+ xfs_extlen_t extsz;520520+ xfs_fsize_t isize;644521 int nimaps;645645- int error;646522 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];647647- int aeof;648648- int fsynced = 0;523523+ int prealloc, fsynced = 0;524524+ int error;649525650526 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);651527···655527 * Make sure that the dquots are there. This doesn't hold656528 * the ilock across a disk read.657529 */658658-659530 error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);660531 if (error)661532 return XFS_ERROR(error);662533534534+ if (XFS_IS_REALTIME_INODE(ip)) {535535+ if (!(extsz = ip->i_d.di_extsize))536536+ extsz = mp->m_sb.sb_rextsize;537537+ } else {538538+ extsz = ip->i_d.di_extsize;539539+ }540540+541541+ offset_fsb = XFS_B_TO_FSBT(mp, offset);542542+663543retry:664544 isize = ip->i_d.di_size;665665- if (io->io_new_size > isize) {545545+ if (io->io_new_size > isize)666546 isize = io->io_new_size;667667- }668547669669- aeof = 0;670670- offset_fsb = XFS_B_TO_FSBT(mp, offset);671671- last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));672672- /*673673- * If the caller is doing a write at the end of the file,674674- * then extend the allocation (and the buffer used for the write)675675- * out to the file system's write iosize. We clean up any extra676676- * space left over when the file is closed in xfs_inactive().677677- *678678- * For sync writes, we are flushing delayed allocate space to679679- * try to make additional space available for allocation near680680- * the filesystem full boundary - preallocation hurts in that681681- * situation, of course.682682- */683683- if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) {684684- xfs_off_t aligned_offset;685685- xfs_filblks_t count_fsb;686686- unsigned int iosize;687687- xfs_fileoff_t ioalign;688688- int n;689689- xfs_fileoff_t start_fsb;548548+ error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count,549549+ ioflag, imap, XFS_WRITE_IMAPS, &prealloc);550550+ if (error)551551+ return error;690552691691- /*692692- * If there are any real blocks past eof, then don't693693- * do any speculative allocation.694694- */695695- start_fsb = XFS_B_TO_FSBT(mp,696696- ((xfs_ufsize_t)(offset + count - 1)));697697- count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));698698- while (count_fsb > 0) {699699- nimaps = XFS_WRITE_IMAPS;700700- error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,701701- 0, &firstblock, 0, imap, &nimaps, NULL);702702- if (error) {703703- return error;704704- }705705- for (n = 0; n < nimaps; n++) {706706- if ( !(io->io_flags & XFS_IOCORE_RT) && 707707- !imap[n].br_startblock) {708708- cmn_err(CE_PANIC,"Access to block "709709- "zero: fs <%s> inode: %lld "710710- "start_block : %llx start_off "711711- ": %llx blkcnt : %llx "712712- "extent-state : %x \n",713713- (ip->i_mount)->m_fsname,714714- (long long)ip->i_ino,715715- imap[n].br_startblock,716716- imap[n].br_startoff,717717- imap[n].br_blockcount,718718- imap[n].br_state);719719- }720720- if ((imap[n].br_startblock != HOLESTARTBLOCK) &&721721- (imap[n].br_startblock != DELAYSTARTBLOCK)) {722722- goto write_map;723723- }724724- start_fsb += imap[n].br_blockcount;725725- count_fsb -= imap[n].br_blockcount;726726- }727727- }728728- iosize = mp->m_writeio_blocks;553553+ if (prealloc) {729554 aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));730555 ioalign = XFS_B_TO_FSBT(mp, aligned_offset);731731- last_fsb = ioalign + iosize;732732- aeof = 1;556556+ last_fsb = ioalign + mp->m_writeio_blocks;557557+ } else {558558+ last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));733559 }734734-write_map:560560+561561+ if (prealloc || extsz) {562562+ error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,563563+ &last_fsb);564564+ if (error)565565+ return error;566566+ }567567+735568 nimaps = XFS_WRITE_IMAPS;736569 firstblock = NULLFSBLOCK;737737-738738- /*739739- * If mounted with the "-o swalloc" option, roundup the allocation740740- * request to a stripe width boundary if the file size is >=741741- * stripe width and we are allocating past the allocation eof.742742- */743743- if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_swidth 744744- && (mp->m_flags & XFS_MOUNT_SWALLOC)745745- && (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)) && aeof) {746746- int eof;747747- xfs_fileoff_t new_last_fsb;748748-749749- new_last_fsb = roundup_64(last_fsb, mp->m_swidth);750750- error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);751751- if (error) {752752- return error;753753- }754754- if (eof) {755755- last_fsb = new_last_fsb;756756- }757757- /*758758- * Roundup the allocation request to a stripe unit (m_dalign) boundary759759- * if the file size is >= stripe unit size, and we are allocating past760760- * the allocation eof.761761- */762762- } else if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_dalign &&763763- (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)) && aeof) {764764- int eof;765765- xfs_fileoff_t new_last_fsb;766766- new_last_fsb = roundup_64(last_fsb, mp->m_dalign);767767- error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);768768- if (error) {769769- return error;770770- }771771- if (eof) {772772- last_fsb = new_last_fsb;773773- }774774- /*775775- * Round up the allocation request to a real-time extent boundary776776- * if the file is on the real-time subvolume.777777- */778778- } else if (io->io_flags & XFS_IOCORE_RT && aeof) {779779- int eof;780780- xfs_fileoff_t new_last_fsb;781781-782782- new_last_fsb = roundup_64(last_fsb, mp->m_sb.sb_rextsize);783783- error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);784784- if (error) {785785- return error;786786- }787787- if (eof)788788- last_fsb = new_last_fsb;789789- }790570 error = xfs_bmapi(NULL, ip, offset_fsb,791571 (xfs_filblks_t)(last_fsb - offset_fsb),792572 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |793573 XFS_BMAPI_ENTIRE, &firstblock, 1, imap,794574 &nimaps, NULL);795795- /*796796- * This can be EDQUOT, if nimaps == 0797797- */798798- if (error && (error != ENOSPC)) {575575+ if (error && (error != ENOSPC))799576 return XFS_ERROR(error);800800- }577577+801578 /*802579 * If bmapi returned us nothing, and if we didn't get back EDQUOT,803803- * then we must have run out of space.580580+ * then we must have run out of space - flush delalloc, and retry..804581 */805582 if (nimaps == 0) {806583 xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,···717684 goto retry;718685 }719686720720- *ret_imap = imap[0];721721- *nmaps = 1;722722- if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {687687+ if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {723688 cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "724689 "start_block : %llx start_off : %llx blkcnt : %llx "725690 "extent-state : %x \n",726691 (ip->i_mount)->m_fsname,727692 (long long)ip->i_ino,728728- ret_imap->br_startblock, ret_imap->br_startoff,729729- ret_imap->br_blockcount,ret_imap->br_state);693693+ (unsigned long long)ret_imap->br_startblock,694694+ (unsigned long long)ret_imap->br_startoff,695695+ (unsigned long long)ret_imap->br_blockcount,696696+ ret_imap->br_state);730697 }698698+699699+ *ret_imap = imap[0];700700+ *nmaps = 1;701701+731702 return 0;732703}733704···857820 */858821859822 for (i = 0; i < nimaps; i++) {860860- if ( !(io->io_flags & XFS_IOCORE_RT) && 861861- !imap[i].br_startblock) {823823+ if (!(io->io_flags & XFS_IOCORE_RT) &&824824+ !imap[i].br_startblock) {862825 cmn_err(CE_PANIC,"Access to block zero: "863826 "fs <%s> inode: %lld "864864- "start_block : %llx start_off : %llx " 827827+ "start_block : %llx start_off : %llx "865828 "blkcnt : %llx extent-state : %x \n",866829 (ip->i_mount)->m_fsname,867830 (long long)ip->i_ino,868868- imap[i].br_startblock,869869- imap[i].br_startoff,870870- imap[i].br_blockcount,imap[i].br_state);831831+ (unsigned long long)832832+ imap[i].br_startblock,833833+ (unsigned long long)834834+ imap[i].br_startoff,835835+ (unsigned long long)836836+ imap[i].br_blockcount,837837+ imap[i].br_state);871838 }872839 if ((offset_fsb >= imap[i].br_startoff) &&873840 (offset_fsb < (imap[i].br_startoff +···908867{909868 xfs_mount_t *mp = ip->i_mount;910869 xfs_iocore_t *io = &ip->i_iocore;911911- xfs_trans_t *tp;912870 xfs_fileoff_t offset_fsb;913871 xfs_filblks_t count_fsb;914872 xfs_filblks_t numblks_fsb;915915- xfs_bmbt_irec_t imap;873873+ xfs_fsblock_t firstfsb;874874+ int nimaps;875875+ xfs_trans_t *tp;876876+ xfs_bmbt_irec_t imap;877877+ xfs_bmap_free_t free_list;878878+ uint resblks;916879 int committed;917880 int error;918918- int nres;919919- int nimaps;920920- xfs_fsblock_t firstfsb;921921- xfs_bmap_free_t free_list;922881923882 xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN,924883 &ip->i_iocore, offset, count);···927886 count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);928887 count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);929888930930- do {931931- nres = XFS_DIOSTRAT_SPACE_RES(mp, 0);889889+ resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;932890891891+ do {933892 /*934893 * set up a transaction to convert the range of extents935894 * from unwritten to real. Do allocations in a loop until···937896 */938897939898 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);940940- error = xfs_trans_reserve(tp, nres,899899+ error = xfs_trans_reserve(tp, resblks,941900 XFS_WRITE_LOG_RES(mp), 0,942901 XFS_TRANS_PERM_LOG_RES,943902 XFS_WRITE_LOG_COUNT);···956915 XFS_BMAP_INIT(&free_list, &firstfsb);957916 nimaps = 1;958917 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,959959- XFS_BMAPI_WRITE, &firstfsb,918918+ XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,960919 1, &imap, &nimaps, &free_list);961920 if (error)962921 goto error_on_bmapi_transaction;···970929 xfs_iunlock(ip, XFS_ILOCK_EXCL);971930 if (error)972931 goto error0;973973-932932+974933 if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) {975934 cmn_err(CE_PANIC,"Access to block zero: fs <%s> "976935 "inode: %lld start_block : %llx start_off : "977936 "%llx blkcnt : %llx extent-state : %x \n",978937 (ip->i_mount)->m_fsname,979938 (long long)ip->i_ino,980980- imap.br_startblock,imap.br_startoff,981981- imap.br_blockcount,imap.br_state);939939+ (unsigned long long)imap.br_startblock,940940+ (unsigned long long)imap.br_startoff,941941+ (unsigned long long)imap.br_blockcount,942942+ imap.br_state);982943 }983944984945 if ((numblks_fsb = imap.br_blockcount) == 0) {
···178178#define xlog_trace_iclog(iclog,state)179179#endif /* XFS_LOG_TRACE */180180181181+182182+static void183183+xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)184184+{185185+ if (*qp) {186186+ tic->t_next = (*qp);187187+ tic->t_prev = (*qp)->t_prev;188188+ (*qp)->t_prev->t_next = tic;189189+ (*qp)->t_prev = tic;190190+ } else {191191+ tic->t_prev = tic->t_next = tic;192192+ *qp = tic;193193+ }194194+195195+ tic->t_flags |= XLOG_TIC_IN_Q;196196+}197197+198198+static void199199+xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)200200+{201201+ if (tic == tic->t_next) {202202+ *qp = NULL;203203+ } else {204204+ *qp = tic->t_next;205205+ tic->t_next->t_prev = tic->t_prev;206206+ tic->t_prev->t_next = tic->t_next;207207+ }208208+209209+ tic->t_next = tic->t_prev = NULL;210210+ tic->t_flags &= ~XLOG_TIC_IN_Q;211211+}212212+213213+static void214214+xlog_grant_sub_space(struct log *log, int bytes)215215+{216216+ log->l_grant_write_bytes -= bytes;217217+ if (log->l_grant_write_bytes < 0) {218218+ log->l_grant_write_bytes += log->l_logsize;219219+ log->l_grant_write_cycle--;220220+ }221221+222222+ log->l_grant_reserve_bytes -= bytes;223223+ if ((log)->l_grant_reserve_bytes < 0) {224224+ log->l_grant_reserve_bytes += log->l_logsize;225225+ log->l_grant_reserve_cycle--;226226+ }227227+228228+}229229+230230+static void231231+xlog_grant_add_space_write(struct log *log, int bytes)232232+{233233+ log->l_grant_write_bytes += bytes;234234+ if (log->l_grant_write_bytes > log->l_logsize) {235235+ log->l_grant_write_bytes -= log->l_logsize;236236+ log->l_grant_write_cycle++;237237+ }238238+}239239+240240+static void241241+xlog_grant_add_space_reserve(struct log *log, int bytes)242242+{243243+ log->l_grant_reserve_bytes += bytes;244244+ if (log->l_grant_reserve_bytes > log->l_logsize) {245245+ log->l_grant_reserve_bytes -= log->l_logsize;246246+ log->l_grant_reserve_cycle++;247247+ }248248+}249249+250250+static inline void251251+xlog_grant_add_space(struct log *log, int bytes)252252+{253253+ xlog_grant_add_space_write(log, bytes);254254+ xlog_grant_add_space_reserve(log, bytes);255255+}256256+257257+181258/*182259 * NOTES:183260 *···505428 if (readonly)506429 vfsp->vfs_flag &= ~VFS_RDONLY;507430508508- error = xlog_recover(mp->m_log, readonly);431431+ error = xlog_recover(mp->m_log);509432510433 if (readonly)511434 vfsp->vfs_flag |= VFS_RDONLY;···1397132013981321 /* move grant heads by roundoff in sync */13991322 s = GRANT_LOCK(log);14001400- XLOG_GRANT_ADD_SPACE(log, roundoff, 'w');14011401- XLOG_GRANT_ADD_SPACE(log, roundoff, 'r');13231323+ xlog_grant_add_space(log, roundoff);14021324 GRANT_UNLOCK(log, s);1403132514041326 /* put cycle number in every block */···15911515 * print out info relating to regions written which consume15921516 * the reservation15931517 */15941594-#if defined(XFS_LOG_RES_DEBUG)15951518STATIC void15961519xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)15971520{···16801605 ticket->t_res_arr_sum, ticket->t_res_o_flow,16811606 ticket->t_res_num_ophdrs, ophdr_spc,16821607 ticket->t_res_arr_sum + 16831683- ticket->t_res_o_flow + ophdr_spc,16081608+ ticket->t_res_o_flow + ophdr_spc,16841609 ticket->t_res_num);1685161016861611 for (i = 0; i < ticket->t_res_num; i++) {16871687- uint r_type = ticket->t_res_arr[i].r_type; 16121612+ uint r_type = ticket->t_res_arr[i].r_type; 16881613 cmn_err(CE_WARN,16891614 "region[%u]: %s - %u bytes\n",16901615 i, ···16931618 ticket->t_res_arr[i].r_len);16941619 }16951620}16961696-#else16971697-#define xlog_print_tic_res(mp, ticket)16981698-#endif1699162117001622/*17011623 * Write some region out to in-core log···2461238924622390 /* something is already sleeping; insert new transaction at end */24632391 if (log->l_reserve_headq) {24642464- XLOG_INS_TICKETQ(log->l_reserve_headq, tic);23922392+ xlog_ins_ticketq(&log->l_reserve_headq, tic);24652393 xlog_trace_loggrant(log, tic,24662394 "xlog_grant_log_space: sleep 1");24672395 /*···24942422 log->l_grant_reserve_bytes);24952423 if (free_bytes < need_bytes) {24962424 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)24972497- XLOG_INS_TICKETQ(log->l_reserve_headq, tic);24252425+ xlog_ins_ticketq(&log->l_reserve_headq, tic);24982426 xlog_trace_loggrant(log, tic,24992427 "xlog_grant_log_space: sleep 2");25002428 XFS_STATS_INC(xs_sleep_logspace);···25112439 s = GRANT_LOCK(log);25122440 goto redo;25132441 } else if (tic->t_flags & XLOG_TIC_IN_Q)25142514- XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);24422442+ xlog_del_ticketq(&log->l_reserve_headq, tic);2515244325162444 /* we've got enough space */25172517- XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w');25182518- XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r');24452445+ xlog_grant_add_space(log, need_bytes);25192446#ifdef DEBUG25202447 tail_lsn = log->l_tail_lsn;25212448 /*···2535246425362465 error_return:25372466 if (tic->t_flags & XLOG_TIC_IN_Q)25382538- XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);24672467+ xlog_del_ticketq(&log->l_reserve_headq, tic);25392468 xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret");25402469 /*25412470 * If we are failing, make sure the ticket doesn't have any···2604253326052534 if (ntic != log->l_write_headq) {26062535 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)26072607- XLOG_INS_TICKETQ(log->l_write_headq, tic);25362536+ xlog_ins_ticketq(&log->l_write_headq, tic);2608253726092538 xlog_trace_loggrant(log, tic,26102539 "xlog_regrant_write_log_space: sleep 1");···26362565 log->l_grant_write_bytes);26372566 if (free_bytes < need_bytes) {26382567 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)26392639- XLOG_INS_TICKETQ(log->l_write_headq, tic);25682568+ xlog_ins_ticketq(&log->l_write_headq, tic);26402569 XFS_STATS_INC(xs_sleep_logspace);26412570 sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);26422571···26522581 s = GRANT_LOCK(log);26532582 goto redo;26542583 } else if (tic->t_flags & XLOG_TIC_IN_Q)26552655- XLOG_DEL_TICKETQ(log->l_write_headq, tic);25842584+ xlog_del_ticketq(&log->l_write_headq, tic);2656258526572657- XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */25862586+ /* we've got enough space */25872587+ xlog_grant_add_space_write(log, need_bytes);26582588#ifdef DEBUG26592589 tail_lsn = log->l_tail_lsn;26602590 if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) {···2672260026732601 error_return:26742602 if (tic->t_flags & XLOG_TIC_IN_Q)26752675- XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);26032603+ xlog_del_ticketq(&log->l_reserve_headq, tic);26762604 xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret");26772605 /*26782606 * If we are failing, make sure the ticket doesn't have any···27052633 ticket->t_cnt--;2706263427072635 s = GRANT_LOCK(log);27082708- XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');27092709- XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');26362636+ xlog_grant_sub_space(log, ticket->t_curr_res);27102637 ticket->t_curr_res = ticket->t_unit_res;27112638 XLOG_TIC_RESET_RES(ticket);27122639 xlog_trace_loggrant(log, ticket,···27182647 return;27192648 }2720264927212721- XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r');26502650+ xlog_grant_add_space_reserve(log, ticket->t_unit_res);27222651 xlog_trace_loggrant(log, ticket,27232652 "xlog_regrant_reserve_log_space: exit");27242653 xlog_verify_grant_head(log, 0);···27542683 s = GRANT_LOCK(log);27552684 xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");2756268527572757- XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');27582758- XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');26862686+ xlog_grant_sub_space(log, ticket->t_curr_res);2759268727602688 xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current");27612689···27632693 */27642694 if (ticket->t_cnt > 0) {27652695 ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV);27662766- XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'w');27672767- XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'r');26962696+ xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt);27682697 }2769269827702699 xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
+1-10
fs/xfs/xfs_log.h
···969697979898/* Region types for iovec's i_type */9999-#if defined(XFS_LOG_RES_DEBUG)10099#define XLOG_REG_TYPE_BFORMAT 1101100#define XLOG_REG_TYPE_BCHUNK 2102101#define XLOG_REG_TYPE_EFI_FORMAT 3···116117#define XLOG_REG_TYPE_COMMIT 18117118#define XLOG_REG_TYPE_TRANSHDR 19118119#define XLOG_REG_TYPE_MAX 19119119-#endif120120121121-#if defined(XFS_LOG_RES_DEBUG)122121#define XLOG_VEC_SET_TYPE(vecp, t) ((vecp)->i_type = (t))123123-#else124124-#define XLOG_VEC_SET_TYPE(vecp, t)125125-#endif126126-127122128123typedef struct xfs_log_iovec {129124 xfs_caddr_t i_addr; /* beginning address of region */130125 int i_len; /* length in bytes of region */131131-#if defined(XFS_LOG_RES_DEBUG)132132- uint i_type; /* type of region */133133-#endif126126+ uint i_type; /* type of region */134127} xfs_log_iovec_t;135128136129typedef void* xfs_log_ticket_t;
···783783xlog_find_tail(784784 xlog_t *log,785785 xfs_daddr_t *head_blk,786786- xfs_daddr_t *tail_blk,787787- int readonly)786786+ xfs_daddr_t *tail_blk)788787{789788 xlog_rec_header_t *rhead;790789 xlog_op_header_t *op_head;···2562256325632564 /*25642565 * The logitem format's flag tells us if this was user quotaoff,25652565- * group quotaoff or both.25662566+ * group/project quotaoff or both.25662567 */25672568 if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)25682569 log->l_quotaoffs_flag |= XFS_DQ_USER;25702570+ if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)25712571+ log->l_quotaoffs_flag |= XFS_DQ_PROJ;25692572 if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)25702573 log->l_quotaoffs_flag |= XFS_DQ_GROUP;25712574···38913890 */38923891int38933892xlog_recover(38943894- xlog_t *log,38953895- int readonly)38933893+ xlog_t *log)38963894{38973895 xfs_daddr_t head_blk, tail_blk;38983896 int error;3899389739003898 /* find the tail of the log */39013901- if ((error = xlog_find_tail(log, &head_blk, &tail_blk, readonly)))38993899+ if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))39023900 return error;3903390139043902 if (tail_blk != head_blk) {
+2-3
fs/xfs/xfs_mount.c
···5151STATIC void xfs_uuid_unmount(xfs_mount_t *mp);5252STATIC void xfs_unmountfs_wait(xfs_mount_t *);53535454-static struct {5454+static const struct {5555 short offset;5656 short type; /* 0 = integer5757 * 1 = binary / string (no translation)···1077107710781078 xfs_iflush_all(mp);1079107910801080- XFS_QM_DQPURGEALL(mp,10811081- XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);10801080+ XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);1082108110831082 /*10841083 * Flush out the log synchronously so that we know for sure
+1-2
fs/xfs/xfs_mount.h
···308308 xfs_buftarg_t *m_ddev_targp; /* saves taking the address */309309 xfs_buftarg_t *m_logdev_targp;/* ptr to log device */310310 xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */311311-#define m_dev m_ddev_targp->pbr_dev312311 __uint8_t m_dircook_elog; /* log d-cookie entry bits */313312 __uint8_t m_blkbit_log; /* blocklog + NBBY */314313 __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */···392393 user */393394#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment394395 allocations */395395-#define XFS_MOUNT_COMPAT_ATTR (1ULL << 8) /* do not use attr2 format */396396+#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */396397 /* (1ULL << 9) -- currently unused */397398#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */398399#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */
+2-5
fs/xfs/xfs_rename.c
···243243 xfs_inode_t *inodes[4];244244 int target_ip_dropped = 0; /* dropped target_ip link? */245245 vnode_t *src_dir_vp;246246- bhv_desc_t *target_dir_bdp;247246 int spaceres;248247 int target_link_zero = 0;249248 int num_inodes;···259260 * Find the XFS behavior descriptor for the target directory260261 * vnode since it was not handed to us.261262 */262262- target_dir_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(target_dir_vp),263263- &xfs_vnodeops);264264- if (target_dir_bdp == NULL) {263263+ target_dp = xfs_vtoi(target_dir_vp);264264+ if (target_dp == NULL) {265265 return XFS_ERROR(EXDEV);266266 }267267268268 src_dp = XFS_BHVTOI(src_dir_bdp);269269- target_dp = XFS_BHVTOI(target_dir_bdp);270269 mp = src_dp->i_mount;271270272271 if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
+4-5
fs/xfs/xfs_rw.c
···238238 }239239 return (EIO);240240}241241+241242/*242243 * Prints out an ALERT message about I/O error.243244 */···253252 "I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"254253 " (\"%s\") error %d buf count %zd",255254 (!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,256256- XFS_BUFTARG_NAME(bp->pb_target),257257- (__uint64_t)blkno,258258- func,259259- XFS_BUF_GETERROR(bp),260260- XFS_BUF_COUNT(bp));255255+ XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),256256+ (__uint64_t)blkno, func,257257+ XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp));261258}262259263260/*
···10141014 xfs_log_item_t *lip;10151015 int i;10161016#endif10171017+ xfs_mount_t *mp = tp->t_mountp;1017101810181019 /*10191020 * See if the caller is being too lazy to figure out if···10271026 * filesystem. This happens in paths where we detect10281027 * corruption and decide to give up.10291028 */10301030- if ((tp->t_flags & XFS_TRANS_DIRTY) &&10311031- !XFS_FORCED_SHUTDOWN(tp->t_mountp))10321032- xfs_force_shutdown(tp->t_mountp, XFS_CORRUPT_INCORE);10291029+ if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {10301030+ XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);10311031+ xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);10321032+ }10331033#ifdef DEBUG10341034 if (!(flags & XFS_TRANS_ABORT)) {10351035 licp = &(tp->t_items);···10421040 }1043104110441042 lip = lidp->lid_item;10451045- if (!XFS_FORCED_SHUTDOWN(tp->t_mountp))10431043+ if (!XFS_FORCED_SHUTDOWN(mp))10461044 ASSERT(!(lip->li_type == XFS_LI_EFD));10471045 }10481046 licp = licp->lic_next;···10501048 }10511049#endif10521050 xfs_trans_unreserve_and_mod_sb(tp);10531053- XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp);10511051+ XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp);1054105210551053 if (tp->t_ticket) {10561054 if (flags & XFS_TRANS_RELEASE_LOG_RES) {···10591057 } else {10601058 log_flags = 0;10611059 }10621062- xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);10601060+ xfs_log_done(mp, tp->t_ticket, NULL, log_flags);10631061 }1064106210651063 /* mark this thread as no longer being in a transaction */