···198198 xfs_agino_t pagi_count; /* number of allocated inodes */199199 int pagb_count; /* pagb slots in use */200200 xfs_perag_busy_t *pagb_list; /* unstable blocks */201201+202202+ /*203203+ * Inode allocation search lookup optimisation.204204+ * If the pagino matches, the search for new inodes205205+ * doesn't need to search the near ones again straight away206206+ */207207+ xfs_agino_t pagl_pagino;208208+ xfs_agino_t pagl_leftrec;209209+ xfs_agino_t pagl_rightrec;201210#ifdef __KERNEL__202211 spinlock_t pagb_lock; /* lock for pagb_list */203212
+1-1
fs/xfs/xfs_bmap.c
···37133713 * entry (null if none). Else, *lastxp will be set to the index37143714 * of the found entry; *gotp will contain the entry.37153715 */37163716-xfs_bmbt_rec_host_t * /* pointer to found extent entry */37163716+STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */37173717xfs_bmap_search_multi_extents(37183718 xfs_ifork_t *ifp, /* inode fork pointer */37193719 xfs_fileoff_t bno, /* block number searched for */
-11
fs/xfs/xfs_bmap.h
···392392 int whichfork,393393 int *count);394394395395-/*396396- * Search the extent records for the entry containing block bno.397397- * If bno lies in a hole, point to the next entry. If bno lies398398- * past eof, *eofp will be set, and *prevp will contain the last399399- * entry (null if none). Else, *lastxp will be set to the index400400- * of the found entry; *gotp will contain the entry.401401- */402402-xfs_bmbt_rec_host_t *403403-xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,404404- xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);405405-406395#endif /* __KERNEL__ */407396408397#endif /* __XFS_BMAP_H__ */
+10-10
fs/xfs/xfs_bmap_btree.c
···202202 ext_flag);203203}204204205205-/* Endian flipping versions of the bmbt extraction functions */206206-void207207-xfs_bmbt_disk_get_all(208208- xfs_bmbt_rec_t *r,209209- xfs_bmbt_irec_t *s)210210-{211211- __xfs_bmbt_get_all(get_unaligned_be64(&r->l0),212212- get_unaligned_be64(&r->l1), s);213213-}214214-215205/*216206 * Extract the blockcount field from an on disk bmap extent record.217207 */···804814{805815 *l0 = be64_to_cpu(key->bmbt.br_startoff);806816 *l1 = 0;817817+}818818+819819+/* Endian flipping versions of the bmbt extraction functions */820820+STATIC void821821+xfs_bmbt_disk_get_all(822822+ xfs_bmbt_rec_t *r,823823+ xfs_bmbt_irec_t *s)824824+{825825+ __xfs_bmbt_get_all(get_unaligned_be64(&r->l0),826826+ get_unaligned_be64(&r->l1), s);807827}808828809829STATIC void
···646646}647647648648/*649649- * Get a buffer for the block, return it read in.650650- * Short-form addressing.651651- */652652-int /* error */653653-xfs_btree_read_bufs(654654- xfs_mount_t *mp, /* file system mount point */655655- xfs_trans_t *tp, /* transaction pointer */656656- xfs_agnumber_t agno, /* allocation group number */657657- xfs_agblock_t agbno, /* allocation group block number */658658- uint lock, /* lock flags for read_buf */659659- xfs_buf_t **bpp, /* buffer for agno/agbno */660660- int refval) /* ref count value for buffer */661661-{662662- xfs_buf_t *bp; /* return value */663663- xfs_daddr_t d; /* real disk block address */664664- int error;665665-666666- ASSERT(agno != NULLAGNUMBER);667667- ASSERT(agbno != NULLAGBLOCK);668668- d = XFS_AGB_TO_DADDR(mp, agno, agbno);669669- if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,670670- mp->m_bsize, lock, &bp))) {671671- return error;672672- }673673- ASSERT(!bp || !XFS_BUF_GETERROR(bp));674674- if (bp != NULL) {675675- switch (refval) {676676- case XFS_ALLOC_BTREE_REF:677677- XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);678678- break;679679- case XFS_INO_BTREE_REF:680680- XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);681681- break;682682- }683683- }684684- *bpp = bp;685685- return 0;686686-}687687-688688-/*689649 * Read-ahead the block, don't wait for it, don't return a buffer.690650 * Long-form addressing.691651 */···29112951 * inode we have to copy the single block it was pointing to into the29122952 * inode.29132953 */29142914-int29542954+STATIC int29152955xfs_btree_kill_iroot(29162956 struct xfs_btree_cur *cur)29172957{
-15
fs/xfs/xfs_btree.h
···379379 int refval);/* ref count value for buffer */380380381381/*382382- * Get a buffer for the block, return it read in.383383- * Short-form addressing.384384- */385385-int /* error */386386-xfs_btree_read_bufs(387387- struct xfs_mount *mp, /* file system mount point */388388- struct xfs_trans *tp, /* transaction pointer */389389- xfs_agnumber_t agno, /* allocation group number */390390- xfs_agblock_t agbno, /* allocation group block number */391391- uint lock, /* lock flags for read_buf */392392- struct xfs_buf **bpp, /* buffer for agno/agbno */393393- int refval);/* ref count value for buffer */394394-395395-/*396382 * Read-ahead the block, don't wait for it, don't return a buffer.397383 * Long-form addressing.398384 */···418432int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);419433int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);420434int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);421421-int xfs_btree_kill_iroot(struct xfs_btree_cur *);422435int xfs_btree_insert(struct xfs_btree_cur *, int *);423436int xfs_btree_delete(struct xfs_btree_cur *, int *);424437int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
+410-403
fs/xfs/xfs_ialloc.c
···5757}58585959/*6060- * Lookup the record equal to ino in the btree given by cur.6161- */6262-STATIC int /* error */6363-xfs_inobt_lookup_eq(6464- struct xfs_btree_cur *cur, /* btree cursor */6565- xfs_agino_t ino, /* starting inode of chunk */6666- __int32_t fcnt, /* free inode count */6767- xfs_inofree_t free, /* free inode mask */6868- int *stat) /* success/failure */6969-{7070- cur->bc_rec.i.ir_startino = ino;7171- cur->bc_rec.i.ir_freecount = fcnt;7272- cur->bc_rec.i.ir_free = free;7373- return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);7474-}7575-7676-/*7777- * Lookup the first record greater than or equal to ino7878- * in the btree given by cur.6060+ * Lookup a record by ino in the btree given by cur.7961 */8062int /* error */8181-xfs_inobt_lookup_ge(6363+xfs_inobt_lookup(8264 struct xfs_btree_cur *cur, /* btree cursor */8365 xfs_agino_t ino, /* starting inode of chunk */8484- __int32_t fcnt, /* free inode count */8585- xfs_inofree_t free, /* free inode mask */6666+ xfs_lookup_t dir, /* <=, >=, == */8667 int *stat) /* success/failure */8768{8869 cur->bc_rec.i.ir_startino = ino;8989- cur->bc_rec.i.ir_freecount = fcnt;9090- cur->bc_rec.i.ir_free = free;9191- return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);7070+ cur->bc_rec.i.ir_freecount = 0;7171+ cur->bc_rec.i.ir_free = 0;7272+ return xfs_btree_lookup(cur, dir, stat);9273}93749475/*9595- * Lookup the first record less than or equal to ino9696- * in the btree given by cur.9797- */9898-int /* error */9999-xfs_inobt_lookup_le(100100- struct xfs_btree_cur *cur, /* btree cursor */101101- xfs_agino_t ino, /* starting inode of chunk */102102- __int32_t fcnt, /* free inode count */103103- xfs_inofree_t free, /* free inode mask */104104- int *stat) /* success/failure */105105-{106106- cur->bc_rec.i.ir_startino = ino;107107- cur->bc_rec.i.ir_freecount = fcnt;108108- cur->bc_rec.i.ir_free = free;109109- return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);110110-}111111-112112-/*113113- * Update the record referred to by cur to the value given114114- * by [ino, fcnt, free].7676+ * Update the record referred to by cur to the value given.11577 * This either works (return 0) or gets an EFSCORRUPTED error.11678 */11779STATIC int /* error */11880xfs_inobt_update(11981 struct xfs_btree_cur *cur, /* btree cursor */120120- xfs_agino_t ino, /* starting inode of chunk */121121- __int32_t fcnt, /* free inode count */122122- xfs_inofree_t free) /* free inode mask */8282+ xfs_inobt_rec_incore_t *irec) /* btree record */12383{12484 union xfs_btree_rec rec;12585126126- rec.inobt.ir_startino = cpu_to_be32(ino);127127- rec.inobt.ir_freecount = cpu_to_be32(fcnt);128128- rec.inobt.ir_free = cpu_to_be64(free);8686+ rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);8787+ rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount);8888+ rec.inobt.ir_free = cpu_to_be64(irec->ir_free);12989 return xfs_btree_update(cur, &rec);13090}13191···95135int /* error */96136xfs_inobt_get_rec(97137 struct xfs_btree_cur *cur, /* btree cursor */9898- xfs_agino_t *ino, /* output: starting inode of chunk */9999- __int32_t *fcnt, /* output: number of free inodes */100100- xfs_inofree_t *free, /* output: free inode mask */138138+ xfs_inobt_rec_incore_t *irec, /* btree record */101139 int *stat) /* output: success/failure */102140{103141 union xfs_btree_rec *rec;···103145104146 error = xfs_btree_get_rec(cur, &rec, stat);105147 if (!error && *stat == 1) {106106- *ino = be32_to_cpu(rec->inobt.ir_startino);107107- *fcnt = be32_to_cpu(rec->inobt.ir_freecount);108108- *free = be64_to_cpu(rec->inobt.ir_free);148148+ irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);149149+ irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount);150150+ irec->ir_free = be64_to_cpu(rec->inobt.ir_free);109151 }110152 return error;153153+}154154+155155+/*156156+ * Verify that the number of free inodes in the AGI is correct.157157+ */158158+#ifdef DEBUG159159+STATIC int160160+xfs_check_agi_freecount(161161+ struct xfs_btree_cur *cur,162162+ struct xfs_agi *agi)163163+{164164+ if (cur->bc_nlevels == 1) {165165+ xfs_inobt_rec_incore_t rec;166166+ int freecount = 0;167167+ int error;168168+ int i;169169+170170+ error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);171171+ if (error)172172+ return error;173173+174174+ do {175175+ error = xfs_inobt_get_rec(cur, &rec, &i);176176+ if (error)177177+ return error;178178+179179+ if (i) {180180+ freecount += rec.ir_freecount;181181+ error = xfs_btree_increment(cur, 0, &i);182182+ if (error)183183+ return error;184184+ }185185+ } while (i == 1);186186+187187+ if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))188188+ ASSERT(freecount == be32_to_cpu(agi->agi_freecount));189189+ }190190+ return 0;191191+}192192+#else193193+#define xfs_check_agi_freecount(cur, agi) 0194194+#endif195195+196196+/*197197+ * Initialise a new set of inodes.198198+ */199199+STATIC void200200+xfs_ialloc_inode_init(201201+ struct xfs_mount *mp,202202+ struct xfs_trans *tp,203203+ xfs_agnumber_t agno,204204+ xfs_agblock_t agbno,205205+ xfs_agblock_t length,206206+ unsigned int gen)207207+{208208+ struct xfs_buf *fbuf;209209+ struct xfs_dinode *free;210210+ int blks_per_cluster, nbufs, ninodes;211211+ int version;212212+ int i, j;213213+ xfs_daddr_t d;214214+215215+ /*216216+ * Loop over the new block(s), filling in the inodes.217217+ * For small block sizes, manipulate the inodes in buffers218218+ * which are multiples of the blocks size.219219+ */220220+ if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {221221+ blks_per_cluster = 1;222222+ nbufs = length;223223+ ninodes = mp->m_sb.sb_inopblock;224224+ } else {225225+ blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /226226+ mp->m_sb.sb_blocksize;227227+ nbufs = length / blks_per_cluster;228228+ ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;229229+ }230230+231231+ /*232232+ * Figure out what version number to use in the inodes we create.233233+ * If the superblock version has caught up to the one that supports234234+ * the new inode format, then use the new inode version. Otherwise235235+ * use the old version so that old kernels will continue to be236236+ * able to use the file system.237237+ */238238+ if (xfs_sb_version_hasnlink(&mp->m_sb))239239+ version = 2;240240+ else241241+ version = 1;242242+243243+ for (j = 0; j < nbufs; j++) {244244+ /*245245+ * Get the block.246246+ */247247+ d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));248248+ fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,249249+ mp->m_bsize * blks_per_cluster,250250+ XFS_BUF_LOCK);251251+ ASSERT(fbuf);252252+ ASSERT(!XFS_BUF_GETERROR(fbuf));253253+254254+ /*255255+ * Initialize all inodes in this buffer and then log them.256256+ *257257+ * XXX: It would be much better if we had just one transaction258258+ * to log a whole cluster of inodes instead of all the259259+ * individual transactions causing a lot of log traffic.260260+ */261261+ xfs_biozero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);262262+ for (i = 0; i < ninodes; i++) {263263+ int ioffset = i << mp->m_sb.sb_inodelog;264264+ uint isize = sizeof(struct xfs_dinode);265265+266266+ free = xfs_make_iptr(mp, fbuf, i);267267+ free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);268268+ free->di_version = version;269269+ free->di_gen = cpu_to_be32(gen);270270+ free->di_next_unlinked = cpu_to_be32(NULLAGINO);271271+ xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);272272+ }273273+ xfs_trans_inode_alloc_buf(tp, fbuf);274274+ }111275}112276113277/*···244164{245165 xfs_agi_t *agi; /* allocation group header */246166 xfs_alloc_arg_t args; /* allocation argument structure */247247- int blks_per_cluster; /* fs blocks per inode cluster */248167 xfs_btree_cur_t *cur; /* inode btree cursor */249249- xfs_daddr_t d; /* disk addr of buffer */250168 xfs_agnumber_t agno;251169 int error;252252- xfs_buf_t *fbuf; /* new free inodes' buffer */253253- xfs_dinode_t *free; /* new free inode structure */254254- int i; /* inode counter */255255- int j; /* block counter */256256- int nbufs; /* num bufs of new inodes */170170+ int i;257171 xfs_agino_t newino; /* new first inode's number */258172 xfs_agino_t newlen; /* new number of inodes */259259- int ninodes; /* num inodes per buf */260173 xfs_agino_t thisino; /* current inode number, for loop */261261- int version; /* inode version number to use */262174 int isaligned = 0; /* inode allocation at stripe unit */263175 /* boundary */264264- unsigned int gen;265176266177 args.tp = tp;267178 args.mp = tp->t_mountp;···273202 */274203 agi = XFS_BUF_TO_AGI(agbp);275204 newino = be32_to_cpu(agi->agi_newino);205205+ agno = be32_to_cpu(agi->agi_seqno);276206 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +277207 XFS_IALLOC_BLOCKS(args.mp);278208 if (likely(newino != NULLAGINO &&279209 (args.agbno < be32_to_cpu(agi->agi_length)))) {280280- args.fsbno = XFS_AGB_TO_FSB(args.mp,281281- be32_to_cpu(agi->agi_seqno), args.agbno);210210+ args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);282211 args.type = XFS_ALLOCTYPE_THIS_BNO;283212 args.mod = args.total = args.wasdel = args.isfl =284213 args.userdata = args.minalignslop = 0;···329258 * For now, just allocate blocks up front.330259 */331260 args.agbno = be32_to_cpu(agi->agi_root);332332- args.fsbno = XFS_AGB_TO_FSB(args.mp,333333- be32_to_cpu(agi->agi_seqno), args.agbno);261261+ args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);334262 /*335263 * Allocate a fixed-size extent of inodes.336264 */···352282 if (isaligned && args.fsbno == NULLFSBLOCK) {353283 args.type = XFS_ALLOCTYPE_NEAR_BNO;354284 args.agbno = be32_to_cpu(agi->agi_root);355355- args.fsbno = XFS_AGB_TO_FSB(args.mp,356356- be32_to_cpu(agi->agi_seqno), args.agbno);285285+ args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);357286 args.alignment = xfs_ialloc_cluster_alignment(&args);358287 if ((error = xfs_alloc_vextent(&args)))359288 return error;···363294 return 0;364295 }365296 ASSERT(args.len == args.minlen);366366- /*367367- * Convert the results.368368- */369369- newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);370370- /*371371- * Loop over the new block(s), filling in the inodes.372372- * For small block sizes, manipulate the inodes in buffers373373- * which are multiples of the blocks size.374374- */375375- if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) {376376- blks_per_cluster = 1;377377- nbufs = (int)args.len;378378- ninodes = args.mp->m_sb.sb_inopblock;379379- } else {380380- blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) /381381- args.mp->m_sb.sb_blocksize;382382- nbufs = (int)args.len / blks_per_cluster;383383- ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock;384384- }385385- /*386386- * Figure out what version number to use in the inodes we create.387387- * If the superblock version has caught up to the one that supports388388- * the new inode format, then use the new inode version. Otherwise389389- * use the old version so that old kernels will continue to be390390- * able to use the file system.391391- */392392- if (xfs_sb_version_hasnlink(&args.mp->m_sb))393393- version = 2;394394- else395395- version = 1;396297397298 /*299299+ * Stamp and write the inode buffers.300300+ *398301 * Seed the new inode cluster with a random generation number. This399302 * prevents short-term reuse of generation numbers if a chunk is400303 * freed and then immediately reallocated. We use random numbers401304 * rather than a linear progression to prevent the next generation402305 * number from being easily guessable.403306 */404404- gen = random32();405405- for (j = 0; j < nbufs; j++) {406406- /*407407- * Get the block.408408- */409409- d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno),410410- args.agbno + (j * blks_per_cluster));411411- fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,412412- args.mp->m_bsize * blks_per_cluster,413413- XFS_BUF_LOCK);414414- ASSERT(fbuf);415415- ASSERT(!XFS_BUF_GETERROR(fbuf));307307+ xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len,308308+ random32());416309417417- /*418418- * Initialize all inodes in this buffer and then log them.419419- *420420- * XXX: It would be much better if we had just one transaction to421421- * log a whole cluster of inodes instead of all the individual422422- * transactions causing a lot of log traffic.423423- */424424- xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);425425- for (i = 0; i < ninodes; i++) {426426- int ioffset = i << args.mp->m_sb.sb_inodelog;427427- uint isize = sizeof(struct xfs_dinode);428428-429429- free = xfs_make_iptr(args.mp, fbuf, i);430430- free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);431431- free->di_version = version;432432- free->di_gen = cpu_to_be32(gen);433433- free->di_next_unlinked = cpu_to_be32(NULLAGINO);434434- xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);435435- }436436- xfs_trans_inode_alloc_buf(tp, fbuf);437437- }310310+ /*311311+ * Convert the results.312312+ */313313+ newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);438314 be32_add_cpu(&agi->agi_count, newlen);439315 be32_add_cpu(&agi->agi_freecount, newlen);440440- agno = be32_to_cpu(agi->agi_seqno);441316 down_read(&args.mp->m_peraglock);442317 args.mp->m_perag[agno].pagi_freecount += newlen;443318 up_read(&args.mp->m_peraglock);444319 agi->agi_newino = cpu_to_be32(newino);320320+445321 /*446322 * Insert records describing the new inode chunk into the btree.447323 */···394380 for (thisino = newino;395381 thisino < newino + newlen;396382 thisino += XFS_INODES_PER_CHUNK) {397397- if ((error = xfs_inobt_lookup_eq(cur, thisino,398398- XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) {383383+ cur->bc_rec.i.ir_startino = thisino;384384+ cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK;385385+ cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE;386386+ error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i);387387+ if (error) {399388 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);400389 return error;401390 }402391 ASSERT(i == 0);403403- if ((error = xfs_btree_insert(cur, &i))) {392392+ error = xfs_btree_insert(cur, &i);393393+ if (error) {404394 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);405395 return error;406396 }···557539}558540559541/*542542+ * Try to retrieve the next record to the left/right from the current one.543543+ */544544+STATIC int545545+xfs_ialloc_next_rec(546546+ struct xfs_btree_cur *cur,547547+ xfs_inobt_rec_incore_t *rec,548548+ int *done,549549+ int left)550550+{551551+ int error;552552+ int i;553553+554554+ if (left)555555+ error = xfs_btree_decrement(cur, 0, &i);556556+ else557557+ error = xfs_btree_increment(cur, 0, &i);558558+559559+ if (error)560560+ return error;561561+ *done = !i;562562+ if (i) {563563+ error = xfs_inobt_get_rec(cur, rec, &i);564564+ if (error)565565+ return error;566566+ XFS_WANT_CORRUPTED_RETURN(i == 1);567567+ }568568+569569+ return 0;570570+}571571+572572+STATIC int573573+xfs_ialloc_get_rec(574574+ struct xfs_btree_cur *cur,575575+ xfs_agino_t agino,576576+ xfs_inobt_rec_incore_t *rec,577577+ int *done,578578+ int left)579579+{580580+ int error;581581+ int i;582582+583583+ error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i);584584+ if (error)585585+ return error;586586+ *done = !i;587587+ if (i) {588588+ error = xfs_inobt_get_rec(cur, rec, &i);589589+ if (error)590590+ return error;591591+ XFS_WANT_CORRUPTED_RETURN(i == 1);592592+ }593593+594594+ return 0;595595+}596596+597597+/*560598 * Visible inode allocation functions.561599 */562600···666592 int j; /* result code */667593 xfs_mount_t *mp; /* file system mount structure */668594 int offset; /* index of inode in chunk */669669- xfs_agino_t pagino; /* parent's a.g. relative inode # */670670- xfs_agnumber_t pagno; /* parent's allocation group number */595595+ xfs_agino_t pagino; /* parent's AG relative inode # */596596+ xfs_agnumber_t pagno; /* parent's AG number */671597 xfs_inobt_rec_incore_t rec; /* inode allocation record */672598 xfs_agnumber_t tagno; /* testing allocation group number */673599 xfs_btree_cur_t *tcur; /* temp cursor */···790716 */791717 agno = tagno;792718 *IO_agbp = NULL;719719+720720+ restart_pagno:793721 cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));794722 /*795723 * If pagino is 0 (this is the root inode allocation) use newino.···799723 */800724 if (!pagino)801725 pagino = be32_to_cpu(agi->agi_newino);802802-#ifdef DEBUG803803- if (cur->bc_nlevels == 1) {804804- int freecount = 0;805726806806- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))807807- goto error0;808808- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);809809- do {810810- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,811811- &rec.ir_freecount, &rec.ir_free, &i)))812812- goto error0;813813- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);814814- freecount += rec.ir_freecount;815815- if ((error = xfs_btree_increment(cur, 0, &i)))816816- goto error0;817817- } while (i == 1);727727+ error = xfs_check_agi_freecount(cur, agi);728728+ if (error)729729+ goto error0;818730819819- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||820820- XFS_FORCED_SHUTDOWN(mp));821821- }822822-#endif823731 /*824824- * If in the same a.g. as the parent, try to get near the parent.732732+ * If in the same AG as the parent, try to get near the parent.825733 */826734 if (pagno == agno) {827827- if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))735735+ xfs_perag_t *pag = &mp->m_perag[agno];736736+ int doneleft; /* done, to the left */737737+ int doneright; /* done, to the right */738738+ int searchdistance = 10;739739+740740+ error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);741741+ if (error)828742 goto error0;829829- if (i != 0 &&830830- (error = xfs_inobt_get_rec(cur, &rec.ir_startino,831831- &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&832832- j == 1 &&833833- rec.ir_freecount > 0) {743743+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);744744+745745+ error = xfs_inobt_get_rec(cur, &rec, &j);746746+ if (error)747747+ goto error0;748748+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);749749+750750+ if (rec.ir_freecount > 0) {834751 /*835752 * Found a free inode in the same chunk836836- * as parent, done.753753+ * as the parent, done.837754 */755755+ goto alloc_inode;838756 }757757+758758+839759 /*840840- * In the same a.g. as parent, but parent's chunk is full.760760+ * In the same AG as parent, but parent's chunk is full.841761 */842842- else {843843- int doneleft; /* done, to the left */844844- int doneright; /* done, to the right */845762763763+ /* duplicate the cursor, search left & right simultaneously */764764+ error = xfs_btree_dup_cursor(cur, &tcur);765765+ if (error)766766+ goto error0;767767+768768+ /*769769+ * Skip to last blocks looked up if same parent inode.770770+ */771771+ if (pagino != NULLAGINO &&772772+ pag->pagl_pagino == pagino &&773773+ pag->pagl_leftrec != NULLAGINO &&774774+ pag->pagl_rightrec != NULLAGINO) {775775+ error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,776776+ &trec, &doneleft, 1);846777 if (error)847847- goto error0;848848- ASSERT(i == 1);849849- ASSERT(j == 1);850850- /*851851- * Duplicate the cursor, search left & right852852- * simultaneously.853853- */854854- if ((error = xfs_btree_dup_cursor(cur, &tcur)))855855- goto error0;856856- /*857857- * Search left with tcur, back up 1 record.858858- */859859- if ((error = xfs_btree_decrement(tcur, 0, &i)))860778 goto error1;861861- doneleft = !i;862862- if (!doneleft) {863863- if ((error = xfs_inobt_get_rec(tcur,864864- &trec.ir_startino,865865- &trec.ir_freecount,866866- &trec.ir_free, &i)))867867- goto error1;868868- XFS_WANT_CORRUPTED_GOTO(i == 1, error1);869869- }870870- /*871871- * Search right with cur, go forward 1 record.872872- */873873- if ((error = xfs_btree_increment(cur, 0, &i)))874874- goto error1;875875- doneright = !i;876876- if (!doneright) {877877- if ((error = xfs_inobt_get_rec(cur,878878- &rec.ir_startino,879879- &rec.ir_freecount,880880- &rec.ir_free, &i)))881881- goto error1;882882- XFS_WANT_CORRUPTED_GOTO(i == 1, error1);883883- }884884- /*885885- * Loop until we find the closest inode chunk886886- * with a free one.887887- */888888- while (!doneleft || !doneright) {889889- int useleft; /* using left inode890890- chunk this time */891779892892- /*893893- * Figure out which block is closer,894894- * if both are valid.895895- */896896- if (!doneleft && !doneright)897897- useleft =898898- pagino -899899- (trec.ir_startino +900900- XFS_INODES_PER_CHUNK - 1) <901901- rec.ir_startino - pagino;902902- else903903- useleft = !doneleft;904904- /*905905- * If checking the left, does it have906906- * free inodes?907907- */908908- if (useleft && trec.ir_freecount) {909909- /*910910- * Yes, set it up as the chunk to use.911911- */912912- rec = trec;913913- xfs_btree_del_cursor(cur,914914- XFS_BTREE_NOERROR);915915- cur = tcur;916916- break;917917- }918918- /*919919- * If checking the right, does it have920920- * free inodes?921921- */922922- if (!useleft && rec.ir_freecount) {923923- /*924924- * Yes, it's already set up.925925- */926926- xfs_btree_del_cursor(tcur,927927- XFS_BTREE_NOERROR);928928- break;929929- }930930- /*931931- * If used the left, get another one932932- * further left.933933- */934934- if (useleft) {935935- if ((error = xfs_btree_decrement(tcur, 0,936936- &i)))937937- goto error1;938938- doneleft = !i;939939- if (!doneleft) {940940- if ((error = xfs_inobt_get_rec(941941- tcur,942942- &trec.ir_startino,943943- &trec.ir_freecount,944944- &trec.ir_free, &i)))945945- goto error1;946946- XFS_WANT_CORRUPTED_GOTO(i == 1,947947- error1);948948- }949949- }950950- /*951951- * If used the right, get another one952952- * further right.953953- */954954- else {955955- if ((error = xfs_btree_increment(cur, 0,956956- &i)))957957- goto error1;958958- doneright = !i;959959- if (!doneright) {960960- if ((error = xfs_inobt_get_rec(961961- cur,962962- &rec.ir_startino,963963- &rec.ir_freecount,964964- &rec.ir_free, &i)))965965- goto error1;966966- XFS_WANT_CORRUPTED_GOTO(i == 1,967967- error1);968968- }969969- }970970- }971971- ASSERT(!doneleft || !doneright);780780+ error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,781781+ &rec, &doneright, 0);782782+ if (error)783783+ goto error1;784784+ } else {785785+ /* search left with tcur, back up 1 record */786786+ error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1);787787+ if (error)788788+ goto error1;789789+790790+ /* search right with cur, go forward 1 record. */791791+ error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0);792792+ if (error)793793+ goto error1;972794 }795795+796796+ /*797797+ * Loop until we find an inode chunk with a free inode.798798+ */799799+ while (!doneleft || !doneright) {800800+ int useleft; /* using left inode chunk this time */801801+802802+ if (!--searchdistance) {803803+ /*804804+ * Not in range - save last search805805+ * location and allocate a new inode806806+ */807807+ pag->pagl_leftrec = trec.ir_startino;808808+ pag->pagl_rightrec = rec.ir_startino;809809+ pag->pagl_pagino = pagino;810810+ goto newino;811811+ }812812+813813+ /* figure out the closer block if both are valid. */814814+ if (!doneleft && !doneright) {815815+ useleft = pagino -816816+ (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) <817817+ rec.ir_startino - pagino;818818+ } else {819819+ useleft = !doneleft;820820+ }821821+822822+ /* free inodes to the left? */823823+ if (useleft && trec.ir_freecount) {824824+ rec = trec;825825+ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);826826+ cur = tcur;827827+828828+ pag->pagl_leftrec = trec.ir_startino;829829+ pag->pagl_rightrec = rec.ir_startino;830830+ pag->pagl_pagino = pagino;831831+ goto alloc_inode;832832+ }833833+834834+ /* free inodes to the right? */835835+ if (!useleft && rec.ir_freecount) {836836+ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);837837+838838+ pag->pagl_leftrec = trec.ir_startino;839839+ pag->pagl_rightrec = rec.ir_startino;840840+ pag->pagl_pagino = pagino;841841+ goto alloc_inode;842842+ }843843+844844+ /* get next record to check */845845+ if (useleft) {846846+ error = xfs_ialloc_next_rec(tcur, &trec,847847+ &doneleft, 1);848848+ } else {849849+ error = xfs_ialloc_next_rec(cur, &rec,850850+ &doneright, 0);851851+ }852852+ if (error)853853+ goto error1;854854+ }855855+856856+ /*857857+ * We've reached the end of the btree. because858858+ * we are only searching a small chunk of the859859+ * btree each search, there is obviously free860860+ * inodes closer to the parent inode than we861861+ * are now. restart the search again.862862+ */863863+ pag->pagl_pagino = NULLAGINO;864864+ pag->pagl_leftrec = NULLAGINO;865865+ pag->pagl_rightrec = NULLAGINO;866866+ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);867867+ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);868868+ goto restart_pagno;973869 }870870+974871 /*975975- * In a different a.g. from the parent.872872+ * In a different AG from the parent.976873 * See if the most recently allocated block has any free.977874 */978978- else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {979979- if ((error = xfs_inobt_lookup_eq(cur,980980- be32_to_cpu(agi->agi_newino), 0, 0, &i)))875875+newino:876876+ if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {877877+ error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),878878+ XFS_LOOKUP_EQ, &i);879879+ if (error)981880 goto error0;982982- if (i == 1 &&983983- (error = xfs_inobt_get_rec(cur, &rec.ir_startino,984984- &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&985985- j == 1 &&986986- rec.ir_freecount > 0) {987987- /*988988- * The last chunk allocated in the group still has989989- * a free inode.990990- */991991- }992992- /*993993- * None left in the last group, search the whole a.g.994994- */995995- else {881881+882882+ if (i == 1) {883883+ error = xfs_inobt_get_rec(cur, &rec, &j);996884 if (error)997885 goto error0;998998- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))999999- goto error0;10001000- ASSERT(i == 1);10011001- for (;;) {10021002- if ((error = xfs_inobt_get_rec(cur,10031003- &rec.ir_startino,10041004- &rec.ir_freecount, &rec.ir_free,10051005- &i)))10061006- goto error0;10071007- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);10081008- if (rec.ir_freecount > 0)10091009- break;10101010- if ((error = xfs_btree_increment(cur, 0, &i)))10111011- goto error0;10121012- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);886886+887887+ if (j == 1 && rec.ir_freecount > 0) {888888+ /*889889+ * The last chunk allocated in the group890890+ * still has a free inode.891891+ */892892+ goto alloc_inode;1013893 }1014894 }1015895 }896896+897897+ /*898898+ * None left in the last group, search the whole AG899899+ */900900+ error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);901901+ if (error)902902+ goto error0;903903+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);904904+905905+ for (;;) {906906+ error = xfs_inobt_get_rec(cur, &rec, &i);907907+ if (error)908908+ goto error0;909909+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);910910+ if (rec.ir_freecount > 0)911911+ break;912912+ error = xfs_btree_increment(cur, 0, &i);913913+ if (error)914914+ goto error0;915915+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);916916+ }917917+918918+alloc_inode:1016919 offset = xfs_ialloc_find_free(&rec.ir_free);1017920 ASSERT(offset >= 0);1018921 ASSERT(offset < XFS_INODES_PER_CHUNK);···1000945 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);1001946 rec.ir_free &= ~XFS_INOBT_MASK(offset);1002947 rec.ir_freecount--;10031003- if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,10041004- rec.ir_free)))948948+ error = xfs_inobt_update(cur, &rec);949949+ if (error)1005950 goto error0;1006951 be32_add_cpu(&agi->agi_freecount, -1);1007952 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);1008953 down_read(&mp->m_peraglock);1009954 mp->m_perag[tagno].pagi_freecount--;1010955 up_read(&mp->m_peraglock);10111011-#ifdef DEBUG10121012- if (cur->bc_nlevels == 1) {10131013- int freecount = 0;101495610151015- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))10161016- goto error0;10171017- do {10181018- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,10191019- &rec.ir_freecount, &rec.ir_free, &i)))10201020- goto error0;10211021- XFS_WANT_CORRUPTED_GOTO(i == 1, error0);10221022- freecount += rec.ir_freecount;10231023- if ((error = xfs_btree_increment(cur, 0, &i)))10241024- goto error0;10251025- } while (i == 1);10261026- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||10271027- XFS_FORCED_SHUTDOWN(mp));10281028- }10291029-#endif957957+ error = xfs_check_agi_freecount(cur, agi);958958+ if (error)959959+ goto error0;960960+1030961 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);1031962 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);1032963 *inop = ino;···11031062 * Initialize the cursor.11041063 */11051064 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);11061106-#ifdef DEBUG11071107- if (cur->bc_nlevels == 1) {11081108- int freecount = 0;1109106511101110- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))11111111- goto error0;11121112- do {11131113- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,11141114- &rec.ir_freecount, &rec.ir_free, &i)))11151115- goto error0;11161116- if (i) {11171117- freecount += rec.ir_freecount;11181118- if ((error = xfs_btree_increment(cur, 0, &i)))11191119- goto error0;11201120- }11211121- } while (i == 1);11221122- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||11231123- XFS_FORCED_SHUTDOWN(mp));11241124- }11251125-#endif10661066+ error = xfs_check_agi_freecount(cur, agi);10671067+ if (error)10681068+ goto error0;10691069+11261070 /*11271071 * Look for the entry describing this inode.11281072 */11291129- if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {10731073+ if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {11301074 cmn_err(CE_WARN,11311131- "xfs_difree: xfs_inobt_lookup_le returned() an error %d on %s. Returning error.",10751075+ "xfs_difree: xfs_inobt_lookup returned() an error %d on %s. Returning error.",11321076 error, mp->m_fsname);11331077 goto error0;11341078 }11351079 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);11361136- if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount,11371137- &rec.ir_free, &i))) {10801080+ error = xfs_inobt_get_rec(cur, &rec, &i);10811081+ if (error) {11381082 cmn_err(CE_WARN,11391083 "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.",11401084 error, mp->m_fsname);···11741148 } else {11751149 *delete = 0;1176115011771177- if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) {11511151+ error = xfs_inobt_update(cur, &rec);11521152+ if (error) {11781153 cmn_err(CE_WARN,11791179- "xfs_difree: xfs_inobt_update() returned an error %d on %s. Returning error.",11541154+ "xfs_difree: xfs_inobt_update returned an error %d on %s.",11801155 error, mp->m_fsname);11811156 goto error0;11821157 }11581158+11831159 /* 11841160 * Change the inode free counts and log the ag/sb changes.11851161 */···11931165 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);11941166 }1195116711961196-#ifdef DEBUG11971197- if (cur->bc_nlevels == 1) {11981198- int freecount = 0;11681168+ error = xfs_check_agi_freecount(cur, agi);11691169+ if (error)11701170+ goto error0;1199117112001200- if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))12011201- goto error0;12021202- do {12031203- if ((error = xfs_inobt_get_rec(cur,12041204- &rec.ir_startino,12051205- &rec.ir_freecount,12061206- &rec.ir_free, &i)))12071207- goto error0;12081208- if (i) {12091209- freecount += rec.ir_freecount;12101210- if ((error = xfs_btree_increment(cur, 0, &i)))12111211- goto error0;12121212- }12131213- } while (i == 1);12141214- ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||12151215- XFS_FORCED_SHUTDOWN(mp));12161216- }12171217-#endif12181172 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);12191173 return 0;12201174···13071297 chunk_agbno = agbno - offset_agbno;13081298 } else {13091299 xfs_btree_cur_t *cur; /* inode btree cursor */13101310- xfs_agino_t chunk_agino; /* first agino in inode chunk */13111311- __int32_t chunk_cnt; /* count of free inodes in chunk */13121312- xfs_inofree_t chunk_free; /* mask of free inodes in chunk */13001300+ xfs_inobt_rec_incore_t chunk_rec;13131301 xfs_buf_t *agbp; /* agi buffer */13141302 int i; /* temp state */13151303···13231315 }1324131613251317 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);13261326- error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i);13181318+ error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);13271319 if (error) {13281320 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "13291329- "xfs_inobt_lookup_le() failed");13211321+ "xfs_inobt_lookup() failed");13301322 goto error0;13311323 }1332132413331333- error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt,13341334- &chunk_free, &i);13251325+ error = xfs_inobt_get_rec(cur, &chunk_rec, &i);13351326 if (error) {13361327 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "13371328 "xfs_inobt_get_rec() failed");···13481341 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);13491342 if (error)13501343 return error;13511351- chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino);13441344+ chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino);13521345 offset_agbno = agbno - chunk_agbno;13531346 }13541347
+5-13
fs/xfs/xfs_ialloc.h
···150150 xfs_agnumber_t agno); /* allocation group number */151151152152/*153153- * Lookup the first record greater than or equal to ino154154- * in the btree given by cur.153153+ * Lookup a record by ino in the btree given by cur.155154 */156156-int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino,157157- __int32_t fcnt, xfs_inofree_t free, int *stat);158158-159159-/*160160- * Lookup the first record less than or equal to ino161161- * in the btree given by cur.162162- */163163-int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,164164- __int32_t fcnt, xfs_inofree_t free, int *stat);155155+int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,156156+ xfs_lookup_t dir, int *stat);165157166158/*167159 * Get the data from the pointed-to record.168160 */169169-extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino,170170- __int32_t *fcnt, xfs_inofree_t *free, int *stat);161161+extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur,162162+ xfs_inobt_rec_incore_t *rec, int *stat);171163172164#endif /* __XFS_IALLOC_H__ */
-27
fs/xfs/xfs_iget.c
···8282 memset(&ip->i_df, 0, sizeof(xfs_ifork_t));8383 ip->i_flags = 0;8484 ip->i_update_core = 0;8585- ip->i_update_size = 0;8685 ip->i_delayed_blks = 0;8786 memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));8887 ip->i_size = 0;···453454 }454455 xfs_put_perag(mp, pag);455456 return error;456456-}457457-458458-459459-/*460460- * Look for the inode corresponding to the given ino in the hash table.461461- * If it is there and its i_transp pointer matches tp, return it.462462- * Otherwise, return NULL.463463- */464464-xfs_inode_t *465465-xfs_inode_incore(xfs_mount_t *mp,466466- xfs_ino_t ino,467467- xfs_trans_t *tp)468468-{469469- xfs_inode_t *ip;470470- xfs_perag_t *pag;471471-472472- pag = xfs_get_perag(mp, ino);473473- read_lock(&pag->pag_ici_lock);474474- ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));475475- read_unlock(&pag->pag_ici_lock);476476- xfs_put_perag(mp, pag);477477-478478- /* the returned inode must match the transaction */479479- if (ip && (ip->i_transp != tp))480480- return NULL;481481- return ip;482457}483458484459/*
+4-4
fs/xfs/xfs_inode.c
···651651 return 0;652652}653653654654-void654654+STATIC void655655xfs_dinode_from_disk(656656 xfs_icdinode_t *to,657657 xfs_dinode_t *from)···12471247 * In that case the pages will still be in memory, but the inode size12481248 * will never have been updated.12491249 */12501250-xfs_fsize_t12501250+STATIC xfs_fsize_t12511251xfs_file_last_byte(12521252 xfs_inode_t *ip)12531253{···38373837/*38383838 * Resize an extent indirection array to new_size bytes.38393839 */38403840-void38403840+STATIC void38413841xfs_iext_realloc_indirect(38423842 xfs_ifork_t *ifp, /* inode fork pointer */38433843 int new_size) /* new indirection array size */···38623862/*38633863 * Switch from indirection array to linear (direct) extent allocations.38643864 */38653865-void38653865+STATIC void38663866xfs_iext_indirect_to_direct(38673867 xfs_ifork_t *ifp) /* inode fork pointer */38683868{
···263263 }264264265265 /*266266- * We don't have to worry about re-ordering here because267267- * the update_size field is protected by the inode lock268268- * and we have that held in exclusive mode.269269- */270270- if (ip->i_update_size)271271- ip->i_update_size = 0;272272-273273- /*274266 * Make sure to get the latest atime from the Linux inode.275267 */276268 xfs_synchronize_atime(ip);···704712 * Clear out the fields of the inode log item particular705713 * to the current transaction.706714 */707707- iip->ili_ilock_recur = 0;708708- iip->ili_iolock_recur = 0;709715 iip->ili_flags = 0;710716711717 /*
-2
fs/xfs/xfs_inode_item.h
···137137 struct xfs_inode *ili_inode; /* inode ptr */138138 xfs_lsn_t ili_flush_lsn; /* lsn at last flush */139139 xfs_lsn_t ili_last_lsn; /* lsn at last transaction */140140- unsigned short ili_ilock_recur; /* lock recursion count */141141- unsigned short ili_iolock_recur; /* lock recursion count */142140 unsigned short ili_flags; /* misc flags */143141 unsigned short ili_logged; /* flushed logged data */144142 unsigned int ili_last_fields; /* fields when flushed */
···3939#include "xfs_error.h"4040#include "xfs_btree.h"41414242-int4242+STATIC int4343xfs_internal_inum(4444 xfs_mount_t *mp,4545 xfs_ino_t ino)···353353 int end_of_ag; /* set if we've seen the ag end */354354 int error; /* error code */355355 int fmterror;/* bulkstat formatter result */356356- __int32_t gcnt; /* current btree rec's count */357357- xfs_inofree_t gfree; /* current btree rec's free mask */358358- xfs_agino_t gino; /* current btree rec's start inode */359356 int i; /* loop index */360357 int icount; /* count of inodes good in irbuf */361358 size_t irbsize; /* size of irec buffer in bytes */···439442 * we need to get the remainder of the chunk we're in.440443 */441444 if (agino > 0) {445445+ xfs_inobt_rec_incore_t r;446446+442447 /*443448 * Lookup the inode chunk that this inode lives in.444449 */445445- error = xfs_inobt_lookup_le(cur, agino, 0, 0, &tmp);450450+ error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE,451451+ &tmp);446452 if (!error && /* no I/O error */447453 tmp && /* lookup succeeded */448454 /* got the record, should always work */449449- !(error = xfs_inobt_get_rec(cur, &gino, &gcnt,450450- &gfree, &i)) &&455455+ !(error = xfs_inobt_get_rec(cur, &r, &i)) &&451456 i == 1 &&452457 /* this is the right chunk */453453- agino < gino + XFS_INODES_PER_CHUNK &&458458+ agino < r.ir_startino + XFS_INODES_PER_CHUNK &&454459 /* lastino was not last in chunk */455455- (chunkidx = agino - gino + 1) <460460+ (chunkidx = agino - r.ir_startino + 1) <456461 XFS_INODES_PER_CHUNK &&457462 /* there are some left allocated */458463 xfs_inobt_maskn(chunkidx,459459- XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) {464464+ XFS_INODES_PER_CHUNK - chunkidx) &465465+ ~r.ir_free) {460466 /*461467 * Grab the chunk record. Mark all the462468 * uninteresting inodes (because they're463469 * before our start point) free.464470 */465471 for (i = 0; i < chunkidx; i++) {466466- if (XFS_INOBT_MASK(i) & ~gfree)467467- gcnt++;472472+ if (XFS_INOBT_MASK(i) & ~r.ir_free)473473+ r.ir_freecount++;468474 }469469- gfree |= xfs_inobt_maskn(0, chunkidx);470470- irbp->ir_startino = gino;471471- irbp->ir_freecount = gcnt;472472- irbp->ir_free = gfree;475475+ r.ir_free |= xfs_inobt_maskn(0, chunkidx);476476+ irbp->ir_startino = r.ir_startino;477477+ irbp->ir_freecount = r.ir_freecount;478478+ irbp->ir_free = r.ir_free;473479 irbp++;474474- agino = gino + XFS_INODES_PER_CHUNK;475475- icount = XFS_INODES_PER_CHUNK - gcnt;480480+ agino = r.ir_startino + XFS_INODES_PER_CHUNK;481481+ icount = XFS_INODES_PER_CHUNK - r.ir_freecount;476482 } else {477483 /*478484 * If any of those tests failed, bump the···493493 /*494494 * Start of ag. Lookup the first inode chunk.495495 */496496- error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &tmp);496496+ error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &tmp);497497 icount = 0;498498 }499499 /*···501501 * until we run out of inodes or space in the buffer.502502 */503503 while (irbp < irbufend && icount < ubcount) {504504+ xfs_inobt_rec_incore_t r;505505+504506 /*505507 * Loop as long as we're unable to read the506508 * inode btree.···512510 if (XFS_AGINO_TO_AGBNO(mp, agino) >=513511 be32_to_cpu(agi->agi_length))514512 break;515515- error = xfs_inobt_lookup_ge(cur, agino, 0, 0,516516- &tmp);513513+ error = xfs_inobt_lookup(cur, agino,514514+ XFS_LOOKUP_GE, &tmp);517515 cond_resched();518516 }519517 /*520518 * If ran off the end of the ag either with an error,521519 * or the normal way, set end and stop collecting.522520 */523523- if (error ||524524- (error = xfs_inobt_get_rec(cur, &gino, &gcnt,525525- &gfree, &i)) ||526526- i == 0) {521521+ if (error) {527522 end_of_ag = 1;528523 break;529524 }525525+526526+ error = xfs_inobt_get_rec(cur, &r, &i);527527+ if (error || i == 0) {528528+ end_of_ag = 1;529529+ break;530530+ }531531+530532 /*531533 * If this chunk has any allocated inodes, save it.532534 * Also start read-ahead now for this chunk.533535 */534534- if (gcnt < XFS_INODES_PER_CHUNK) {536536+ if (r.ir_freecount < XFS_INODES_PER_CHUNK) {535537 /*536538 * Loop over all clusters in the next chunk.537539 * Do a readahead if there are any allocated538540 * inodes in that cluster.539541 */540540- for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),541541- chunkidx = 0;542542+ agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);543543+ for (chunkidx = 0;542544 chunkidx < XFS_INODES_PER_CHUNK;543545 chunkidx += nicluster,544546 agbno += nbcluster) {545545- if (xfs_inobt_maskn(chunkidx,546546- nicluster) & ~gfree)547547+ if (xfs_inobt_maskn(chunkidx, nicluster)548548+ & ~r.ir_free)547549 xfs_btree_reada_bufs(mp, agno,548550 agbno, nbcluster);549551 }550550- irbp->ir_startino = gino;551551- irbp->ir_freecount = gcnt;552552- irbp->ir_free = gfree;552552+ irbp->ir_startino = r.ir_startino;553553+ irbp->ir_freecount = r.ir_freecount;554554+ irbp->ir_free = r.ir_free;553555 irbp++;554554- icount += XFS_INODES_PER_CHUNK - gcnt;556556+ icount += XFS_INODES_PER_CHUNK - r.ir_freecount;555557 }556558 /*557559 * Set agino to after this chunk and bump the cursor.558560 */559559- agino = gino + XFS_INODES_PER_CHUNK;561561+ agino = r.ir_startino + XFS_INODES_PER_CHUNK;560562 error = xfs_btree_increment(cur, 0, &tmp);561563 cond_resched();562564 }···826820 int bufidx;827821 xfs_btree_cur_t *cur;828822 int error;829829- __int32_t gcnt;830830- xfs_inofree_t gfree;831831- xfs_agino_t gino;823823+ xfs_inobt_rec_incore_t r;832824 int i;833825 xfs_ino_t ino;834826 int left;···859855 continue;860856 }861857 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno);862862- error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp);858858+ error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE,859859+ &tmp);863860 if (error) {864861 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);865862 cur = NULL;···875870 continue;876871 }877872 }878878- if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree,879879- &i)) ||880880- i == 0) {873873+ error = xfs_inobt_get_rec(cur, &r, &i);874874+ if (error || i == 0) {881875 xfs_buf_relse(agbp);882876 agbp = NULL;883877 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);···885881 agino = 0;886882 continue;887883 }888888- agino = gino + XFS_INODES_PER_CHUNK - 1;889889- buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino);890890- buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt;891891- buffer[bufidx].xi_allocmask = ~gfree;884884+ agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1;885885+ buffer[bufidx].xi_startino =886886+ XFS_AGINO_TO_INO(mp, agno, r.ir_startino);887887+ buffer[bufidx].xi_alloccount =888888+ XFS_INODES_PER_CHUNK - r.ir_freecount;889889+ buffer[bufidx].xi_allocmask = ~r.ir_free;892890 bufidx++;893891 left--;894892 if (bufidx == bcount) {
-5
fs/xfs/xfs_itable.h
···9999 void *dibuff,100100 int *stat);101101102102-int103103-xfs_internal_inum(104104- xfs_mount_t *mp,105105- xfs_ino_t ino);106106-107102typedef int (*inumbers_fmt_pf)(108103 void __user *ubuffer, /* buffer to write to */109104 const xfs_inogrp_t *buffer, /* buffer to read from */
···414414415415extern int xfs_log_sbcount(xfs_mount_t *, uint);416416extern int xfs_mountfs(xfs_mount_t *mp);417417-extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);418417419418extern void xfs_unmountfs(xfs_mount_t *);420419extern int xfs_unmountfs_writesb(xfs_mount_t *);421420extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);422422-extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,423423- int64_t, int);424421extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,425422 uint, int);426423extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
-29
fs/xfs/xfs_mru_cache.c
···564564}565565566566/*567567- * To look up an element using its key, but leave its location in the internal568568- * lists alone, call xfs_mru_cache_peek(). If the element isn't found, this569569- * function returns NULL.570570- *571571- * See the comments above the declaration of the xfs_mru_cache_lookup() function572572- * for important locking information pertaining to this call.573573- */574574-void *575575-xfs_mru_cache_peek(576576- xfs_mru_cache_t *mru,577577- unsigned long key)578578-{579579- xfs_mru_cache_elem_t *elem;580580-581581- ASSERT(mru && mru->lists);582582- if (!mru || !mru->lists)583583- return NULL;584584-585585- spin_lock(&mru->lock);586586- elem = radix_tree_lookup(&mru->store, key);587587- if (!elem)588588- spin_unlock(&mru->lock);589589- else590590- __release(mru_lock); /* help sparse not be stupid */591591-592592- return elem ? elem->value : NULL;593593-}594594-595595-/*596567 * To release the internal data structure spinlock after having performed an597568 * xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done()598569 * with the data store pointer.
-1
fs/xfs/xfs_mru_cache.h
···4949void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key);5050void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key);5151void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key);5252-void *xfs_mru_cache_peek(struct xfs_mru_cache *mru, unsigned long key);5352void xfs_mru_cache_done(struct xfs_mru_cache *mru);54535554#endif /* __XFS_MRU_CACHE_H__ */
-84
fs/xfs/xfs_rw.c
···8888}89899090/*9191- * Handle logging requirements of various synchronous types of write.9292- */9393-int9494-xfs_write_sync_logforce(9595- xfs_mount_t *mp,9696- xfs_inode_t *ip)9797-{9898- int error = 0;9999-100100- /*101101- * If we're treating this as O_DSYNC and we have not updated the102102- * size, force the log.103103- */104104- if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&105105- !(ip->i_update_size)) {106106- xfs_inode_log_item_t *iip = ip->i_itemp;107107-108108- /*109109- * If an allocation transaction occurred110110- * without extending the size, then we have to force111111- * the log up the proper point to ensure that the112112- * allocation is permanent. We can't count on113113- * the fact that buffered writes lock out direct I/O114114- * writes - the direct I/O write could have extended115115- * the size nontransactionally, then finished before116116- * we started. xfs_write_file will think that the file117117- * didn't grow but the update isn't safe unless the118118- * size change is logged.119119- *120120- * Force the log if we've committed a transaction121121- * against the inode or if someone else has and122122- * the commit record hasn't gone to disk (e.g.123123- * the inode is pinned). This guarantees that124124- * all changes affecting the inode are permanent125125- * when we return.126126- */127127- if (iip && iip->ili_last_lsn) {128128- error = _xfs_log_force(mp, iip->ili_last_lsn,129129- XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);130130- } else if (xfs_ipincount(ip) > 0) {131131- error = _xfs_log_force(mp, (xfs_lsn_t)0,132132- XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);133133- }134134-135135- } else {136136- xfs_trans_t *tp;137137-138138- /*139139- * O_SYNC or O_DSYNC _with_ a size update are handled140140- * the same way.141141- *142142- * If the write was synchronous then we need to make143143- * sure that the inode modification time is permanent.144144- * We'll have updated the timestamp above, so here145145- * we use a synchronous transaction to log the inode.146146- * It's not fast, but it's necessary.147147- *148148- * If this a dsync write and the size got changed149149- * non-transactionally, then we need to ensure that150150- * the size change gets logged in a synchronous151151- * transaction.152152- */153153- tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);154154- if ((error = xfs_trans_reserve(tp, 0,155155- XFS_SWRITE_LOG_RES(mp),156156- 0, 0, 0))) {157157- /* Transaction reserve failed */158158- xfs_trans_cancel(tp, 0);159159- } else {160160- /* Transaction reserve successful */161161- xfs_ilock(ip, XFS_ILOCK_EXCL);162162- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);163163- xfs_trans_ihold(tp, ip);164164- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);165165- xfs_trans_set_sync(tp);166166- error = xfs_trans_commit(tp, 0);167167- xfs_iunlock(ip, XFS_ILOCK_EXCL);168168- }169169- }170170-171171- return error;172172-}173173-174174-/*17591 * Force a shutdown of the filesystem instantly while keeping17692 * the filesystem consistent. We don't do an unmount here; just shutdown17793 * the shop, make sure that absolutely nothing persistent happens to
-7
fs/xfs/xfs_rw.h
···6868 * Prototypes for functions in xfs_rw.c.6969 */7070extern int xfs_write_clear_setuid(struct xfs_inode *ip);7171-extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);7271extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);7372extern int xfs_bioerror(struct xfs_buf *bp);7473extern int xfs_bioerror_relse(struct xfs_buf *bp);···7677 struct xfs_buf **bpp);7778extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,7879 xfs_buf_t *bp, xfs_daddr_t blkno);7979-8080-/*8181- * Prototypes for functions in xfs_vnodeops.c.8282- */8383-extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,8484- int flags);85808681#endif /* __XFS_RW_H__ */
···307307 return (flags & XFS_BUF_TRYLOCK) ?308308 EAGAIN : XFS_ERROR(ENOMEM);309309310310- if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) {310310+ if (XFS_BUF_GETERROR(bp) != 0) {311311 xfs_ioerror_alert("xfs_trans_read_buf", mp,312312 bp, blkno);313313 error = XFS_BUF_GETERROR(bp);···315315 return error;316316 }317317#ifdef DEBUG318318- if (xfs_do_error && (bp != NULL)) {318318+ if (xfs_do_error) {319319 if (xfs_error_target == target) {320320 if (((xfs_req_num++) % xfs_error_mod) == 0) {321321 xfs_buf_relse(bp);
+5-81
fs/xfs/xfs_trans_inode.c
···494950505151/*5252- * Get and lock the inode for the caller if it is not already5353- * locked within the given transaction. If it is already locked5454- * within the transaction, just increment its lock recursion count5555- * and return a pointer to it.5656- *5757- * For an inode to be locked in a transaction, the inode lock, as5858- * opposed to the io lock, must be taken exclusively. This ensures5959- * that the inode can be involved in only 1 transaction at a time.6060- * Lock recursion is handled on the io lock, but only for lock modes6161- * of equal or lesser strength. That is, you can recur on the io lock6262- * held EXCL with a SHARED request but not vice versa. Also, if6363- * the inode is already a part of the transaction then you cannot6464- * go from not holding the io lock to having it EXCL or SHARED.6565- *6666- * Use the inode cache routine xfs_inode_incore() to find the inode6767- * if it is already owned by this transaction.6868- *6969- * If we don't already own the inode, use xfs_iget() to get it.7070- * Since the inode log item structure is embedded in the incore7171- * inode structure and is initialized when the inode is brought7272- * into memory, there is nothing to do with it here.7373- *7474- * If the given transaction pointer is NULL, just call xfs_iget().7575- * This simplifies code which must handle both cases.5252+ * Get an inode and join it to the transaction.7653 */7754int7855xfs_trans_iget(···6184 xfs_inode_t **ipp)6285{6386 int error;6464- xfs_inode_t *ip;65876666- /*6767- * If the transaction pointer is NULL, just call the normal6868- * xfs_iget().6969- */7070- if (tp == NULL)7171- return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0);7272-7373- /*7474- * If we find the inode in core with this transaction7575- * pointer in its i_transp field, then we know we already7676- * have it locked. In this case we just increment the lock7777- * recursion count and return the inode to the caller.7878- * Assert that the inode is already locked in the mode requested7979- * by the caller. We cannot do lock promotions yet, so8080- * die if someone gets this wrong.8181- */8282- if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) {8383- /*8484- * Make sure that the inode lock is held EXCL and8585- * that the io lock is never upgraded when the inode8686- * is already a part of the transaction.8787- */8888- ASSERT(ip->i_itemp != NULL);8989- ASSERT(lock_flags & XFS_ILOCK_EXCL);9090- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));9191- ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||9292- xfs_isilocked(ip, XFS_IOLOCK_EXCL));9393- ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||9494- (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL));9595- ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||9696- xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED));9797- ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||9898- (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY));9999-100100- if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {101101- ip->i_itemp->ili_iolock_recur++;102102- }103103- if (lock_flags & XFS_ILOCK_EXCL) {104104- ip->i_itemp->ili_ilock_recur++;105105- }106106- *ipp = ip;107107- return 0;108108- }109109-110110- ASSERT(lock_flags & XFS_ILOCK_EXCL);111111- error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0);112112- if (error) {113113- return error;114114- }115115- ASSERT(ip != NULL);116116-117117- xfs_trans_ijoin(tp, ip, lock_flags);118118- *ipp = ip;119119- return 0;8888+ error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0);8989+ if (!error && tp)9090+ xfs_trans_ijoin(tp, *ipp, lock_flags);9191+ return error;12092}1219312294/*···89163 xfs_inode_item_init(ip, ip->i_mount);90164 iip = ip->i_itemp;91165 ASSERT(iip->ili_flags == 0);9292- ASSERT(iip->ili_ilock_recur == 0);9393- ASSERT(iip->ili_iolock_recur == 0);9416695167 /*96168 * Get a log_item_desc to point at the new item.
+6-11
fs/xfs/xfs_vnodeops.c
···611611 xfs_inode_t *ip)612612{613613 xfs_trans_t *tp;614614- int error;614614+ int error = 0;615615 int log_flushed = 0, changed = 1;616616617617 xfs_itrace_entry(ip);···619619 if (XFS_FORCED_SHUTDOWN(ip->i_mount))620620 return XFS_ERROR(EIO);621621622622- /* capture size updates in I/O completion before writing the inode. */623623- error = xfs_wait_on_pages(ip, 0, -1);624624- if (error)625625- return XFS_ERROR(error);626626-627622 /*628623 * We always need to make sure that the required inode state is safe on629629- * disk. The vnode might be clean but we still might need to force the624624+ * disk. The inode might be clean but we still might need to force the630625 * log because of committed transactions that haven't hit the disk yet.631626 * Likewise, there could be unflushed non-transactional changes to the632627 * inode core that have to go to disk and this requires us to issue···633638 */634639 xfs_ilock(ip, XFS_ILOCK_SHARED);635640636636- if (!(ip->i_update_size || ip->i_update_core)) {641641+ if (!ip->i_update_core) {637642 /*638643 * Timestamps/size haven't changed since last inode flush or639644 * inode transaction commit. That means either nothing got···713718 * when the link count isn't zero and by xfs_dm_punch_hole() when714719 * punching a hole to EOF.715720 */716716-int721721+STATIC int717722xfs_free_eofblocks(718723 xfs_mount_t *mp,719724 xfs_inode_t *ip,···14711476 if (error == ENOSPC) {14721477 /* flush outstanding delalloc blocks and retry */14731478 xfs_flush_inodes(dp);14741474- error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,14751475- XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);14791479+ error = xfs_trans_reserve(tp, resblks, log_res, 0,14801480+ XFS_TRANS_PERM_LOG_RES, log_count);14761481 }14771482 if (error == ENOSPC) {14781483 /* No space at all so try a "no-allocation" reservation */