* [PATCH 00/49] xfsprogs: patches for crc-dev branch
@ 2013-07-19 6:44 Dave Chinner
2013-07-19 6:44 ` [PATCH 01/49] xfsprogs: introduce xfs_icreate.h Dave Chinner
` (49 more replies)
0 siblings, 50 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
Hi folks,
This series is the matching patch series to my for-3.12 kernel
series posted here:
http://oss.sgi.com/pipermail/xfs/2013-July/028207.html
The first 3 patches add icreate transaction support to xfs_logprint.
The next 37 patches update the libxfs code to match the kernel code
in the above patch set - many of the transformations are identical,
and they bring the code bases mostly into synchronisation.
The next 6 patches introduce jeff Liu's transaciton reservation
patchset and integrate it into mkfs to ensure that mkfs.xfs doesn't
create logs that are too small. This version has the "default log
size larger than the AG size so mkfs fails" problems fixed, so all
the xfstests regressions it caused are gone.
THe last 3 patches introduce dirent filetype support into libxfs,
mkfs and xfs_db. xfs_repair can handle the new dirent structures
just fine, but it doesn't yet have code to validate that the
filetype in the dirent matches the inode it points to.
Anyway, this applies to a current crc-dev branch, and should compile
cleanly without warnings. If you do get warnings, let me know,
because I'm getting ready to a -Werror to the build so that it
breaks whenever someone introduces a compile time warning....
Comments, thoughts, flames?
Cheers,
Dave.
$ git diff --stat -C -M --summary --minimal cdc4cb9..
copy/xfs_copy.c | 12 +-
db/bmroot.c | 6 +-
db/check.c | 12 +-
db/dir2.c | 51 +-
db/dir2.h | 1 +
db/dir2sf.c | 61 ++-
db/dir2sf.h | 3 +
db/field.c | 7 +
db/field.h | 3 +
db/inode.c | 23 +-
db/metadump.c | 10 +-
fsr/xfs_fsr.c | 1 -
include/Makefile | 24 +-
include/libxfs.h | 98 +++-
include/libxlog.h | 13 -
include/platform_defs.h.in | 5 +
include/swab.h | 6 +-
include/xfs_ag.h | 55 +-
include/xfs_alloc_btree.h | 3 +-
include/xfs_attr_leaf.h | 1 +
include/xfs_attr_remote.h | 28 +-
include/xfs_bmap.h | 54 +-
include/xfs_bmap_btree.h | 5 +-
include/xfs_btree.h | 3 +-
include/xfs_buf_item.h | 172 ------
include/xfs_da_btree.h | 1 +
include/xfs_dfrag.h | 53 --
include/xfs_dinode.h | 3 -
include/xfs_dir2.h | 20 +-
include/xfs_dir2_format.h | 208 +++++--
include/xfs_extfree_item.h | 161 ------
include/xfs_format.h | 169 ++++++
include/xfs_fs.h | 41 +-
include/xfs_ialloc.h | 8 +
include/xfs_ialloc_btree.h | 3 +-
include/xfs_inode.h | 631 ----------------------
include/xfs_inode_buf.h | 52 ++
include/xfs_inode_fork.h | 171 ++++++
include/xfs_inode_item.h | 170 ------
include/xfs_log.h | 189 -------
include/xfs_log_format.h | 773 +++++++++++++++++++++++++++
include/xfs_log_priv.h | 692 ------------------------
include/xfs_mount.h | 403 --------------
include/xfs_quota.h | 393 --------------
include/xfs_quota_defs.h | 157 ++++++
include/xfs_rtalloc.h | 166 ------
include/xfs_sb.h | 58 +-
include/xfs_symlink.h | 45 --
include/xfs_trace.h | 1 +
include/xfs_trans.h | 224 +-------
include/xfs_trans_resv.h | 116 ++++
include/xfs_types.h | 59 +-
io/init.h | 3 -
libxfs/Makefile | 34 +-
libxfs/init.c | 5 +-
libxfs/rdwr.c | 3 -
libxfs/trans.c | 130 ++++-
libxfs/util.c | 122 ++++-
libxfs/xfs.h | 62 ++-
libxfs/xfs_alloc.c | 37 +-
libxfs/xfs_alloc_btree.c | 23 +-
libxfs/xfs_attr.c | 39 +-
libxfs/xfs_attr_leaf.c | 9 +-
libxfs/xfs_attr_remote.c | 8 +-
libxfs/xfs_bmap.c | 438 ++++-----------
libxfs/xfs_bmap_btree.c | 14 +-
libxfs/xfs_btree.c | 10 +
libxfs/xfs_da_btree.c | 69 +--
libxfs/xfs_dir2.c | 50 +-
libxfs/xfs_dir2_block.c | 44 +-
libxfs/xfs_dir2_data.c | 39 +-
libxfs/xfs_dir2_leaf.c | 17 +-
libxfs/xfs_dir2_node.c | 43 +-
libxfs/xfs_dir2_priv.h | 44 +-
libxfs/xfs_dir2_sf.c | 141 +++--
libxfs/xfs_ialloc.c | 271 ++++++++--
libxfs/xfs_ialloc_btree.c | 16 +-
libxfs/xfs_inode_buf.c | 408 ++++++++++++++
libxfs/{xfs_inode.c => xfs_inode_fork.c} | 425 +--------------
libxfs/xfs_log_rlimit.c | 135 +++++
libxfs/xfs_rtalloc.c | 6 +-
libxfs/{xfs_mount.c => xfs_sb.c} | 118 +++-
libxfs/{xfs_symlink.c => xfs_symlink_remote.c} | 52 +-
libxfs/{xfs_trans.c => xfs_trans_resv.c} | 379 +++++++------
libxlog/xfs_log_recover.c | 3 +
logprint/log_misc.c | 94 +++-
logprint/log_print_all.c | 21 +
mkfs/maxtrres.c | 58 +-
mkfs/proto.c | 24 +-
mkfs/xfs_mkfs.c | 107 ++--
mkfs/xfs_mkfs.h | 4 +-
repair/attr_repair.c | 2 +
repair/dir2.c | 37 +-
repair/dir2.h | 1 +
repair/incore_ino.c | 2 +
repair/phase5.c | 3 +-
repair/phase6.c | 111 ++--
repair/phase7.c | 7 +-
repair/scan.c | 1 +
99 files changed, 4251 insertions(+), 5042 deletions(-)
delete mode 100644 include/xfs_buf_item.h
delete mode 100644 include/xfs_dfrag.h
delete mode 100644 include/xfs_extfree_item.h
create mode 100644 include/xfs_format.h
delete mode 100644 include/xfs_inode.h
create mode 100644 include/xfs_inode_buf.h
create mode 100644 include/xfs_inode_fork.h
delete mode 100644 include/xfs_inode_item.h
delete mode 100644 include/xfs_log.h
create mode 100644 include/xfs_log_format.h
delete mode 100644 include/xfs_log_priv.h
delete mode 100644 include/xfs_mount.h
delete mode 100644 include/xfs_quota.h
create mode 100644 include/xfs_quota_defs.h
delete mode 100644 include/xfs_rtalloc.h
delete mode 100644 include/xfs_symlink.h
create mode 100644 include/xfs_trans_resv.h
create mode 100644 libxfs/xfs_inode_buf.c
rename libxfs/{xfs_inode.c => xfs_inode_fork.c} (82%)
create mode 100644 libxfs/xfs_log_rlimit.c
rename libxfs/{xfs_mount.c => xfs_sb.c} (87%)
rename libxfs/{xfs_symlink.c => xfs_symlink_remote.c} (68%)
rename libxfs/{xfs_trans.c => xfs_trans_resv.c} (67%)
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* [PATCH 01/49] xfsprogs: introduce xfs_icreate.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-01 18:07 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 02/49] xfsprogs: port inode create transaction changes Dave Chinner
` (48 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Bring the new inode create item definitions across from kernel space
for xfs_logprint to be able to parse.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 2 +-
include/xfs_icreate_item.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
include/xfs_log.h | 3 ++-
include/xfs_trans.h | 7 +++++--
4 files changed, 60 insertions(+), 4 deletions(-)
create mode 100644 include/xfs_icreate_item.h
diff --git a/include/Makefile b/include/Makefile
index 92161bd..ba2c80d 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -26,7 +26,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_btree_trace.h xfs_buf_item.h xfs_cksum.h xfs_da_btree.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \
- xfs_inode.h xfs_inode_item.h xfs_inum.h \
+ xfs_icreate_item.h xfs_inode.h xfs_inode_item.h xfs_inum.h \
xfs_log.h xfs_log_priv.h xfs_log_recover.h xfs_metadump.h \
xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h xfs_symlink.h \
xfs_trace.h xfs_trans.h xfs_trans_space.h xfs_dfrag.h
diff --git a/include/xfs_icreate_item.h b/include/xfs_icreate_item.h
new file mode 100644
index 0000000..88ba8aa
--- /dev/null
+++ b/include/xfs_icreate_item.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008-2010, Dave Chinner
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef XFS_ICREATE_ITEM_H
+#define XFS_ICREATE_ITEM_H 1
+
+/*
+ * on disk log item structure
+ *
+ * Log recovery assumes the first two entries are the type and size and they fit
+ * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so
+ * decoding can be done correctly.
+ */
+struct xfs_icreate_log {
+ __uint16_t icl_type; /* type of log format structure */
+ __uint16_t icl_size; /* size of log format structure */
+ __be32 icl_ag; /* ag being allocated in */
+ __be32 icl_agbno; /* start block of inode range */
+ __be32 icl_count; /* number of inodes to initialise */
+ __be32 icl_isize; /* size of inodes */
+ __be32 icl_length; /* length of extent to initialise */
+ __be32 icl_gen; /* inode generation number to use */
+};
+
+/* in memory log item structure */
+struct xfs_icreate_item {
+ struct xfs_log_item ic_item;
+ struct xfs_icreate_log ic_format;
+};
+
+extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
+
+void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno,
+ xfs_agblock_t agbno, unsigned int count,
+ unsigned int inode_size, xfs_agblock_t length,
+ unsigned int generation);
+
+#endif /* XFS_ICREATE_ITEM_H */
diff --git a/include/xfs_log.h b/include/xfs_log.h
index 5caee96..70cc014 100644
--- a/include/xfs_log.h
+++ b/include/xfs_log.h
@@ -88,7 +88,8 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
#define XLOG_REG_TYPE_UNMOUNT 17
#define XLOG_REG_TYPE_COMMIT 18
#define XLOG_REG_TYPE_TRANSHDR 19
-#define XLOG_REG_TYPE_MAX 19
+#define XLOG_REG_TYPE_ICREATE 20
+#define XLOG_REG_TYPE_MAX 20
typedef struct xfs_log_iovec {
void *i_addr; /* beginning address of region */
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index acf1381..36a0026 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -48,6 +48,7 @@ typedef struct xfs_trans_header {
#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
#define XFS_LI_DQUOT 0x123d
#define XFS_LI_QUOTAOFF 0x123e
+#define XFS_LI_ICREATE 0x123f
#define XFS_LI_TYPE_DESC \
{ XFS_LI_EFI, "XFS_LI_EFI" }, \
@@ -56,7 +57,8 @@ typedef struct xfs_trans_header {
{ XFS_LI_INODE, "XFS_LI_INODE" }, \
{ XFS_LI_BUF, "XFS_LI_BUF" }, \
{ XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \
- { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }
+ { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }, \
+ { XFS_LI_ICREATE, "XFS_LI_ICREATE" }
/*
* Transaction types. Used to distinguish types of buffers.
@@ -107,7 +109,8 @@ typedef struct xfs_trans_header {
#define XFS_TRANS_SWAPEXT 40
#define XFS_TRANS_SB_COUNT 41
#define XFS_TRANS_CHECKPOINT 42
-#define XFS_TRANS_TYPE_MAX 42
+#define XFS_TRANS_ICREATE 43
+#define XFS_TRANS_TYPE_MAX 43
/* new transaction types need to be reflected in xfs_logprint(8) */
#define XFS_TRANS_TYPES \
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 02/49] xfsprogs: port inode create transaction changes
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
2013-07-19 6:44 ` [PATCH 01/49] xfsprogs: introduce xfs_icreate.h Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-01 19:01 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 03/49] xfsprogs: teach logprint about icreate transaction Dave Chinner
` (47 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Bring across the relevant parts of the new inode create transaction
sufficient to keep kernel/user code in sync and implement the
infrastructure needed to make it work in xfsprogs.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 1 +
include/xfs_ialloc.h | 8 +++
include/xfs_icreate_item.h | 3 ++
libxfs/xfs.h | 5 ++
libxfs/xfs_ialloc.c | 87 +++++++++++++++++++++++++--------
libxfs/xfs_trans.c | 118 +++++++++++++++++++++++++++++----------------
6 files changed, 160 insertions(+), 62 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index f11ad52..bd74ca5 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -57,6 +57,7 @@
#include <xfs/xfs_bmap.h>
#include <xfs/xfs_trace.h>
#include <xfs/xfs_symlink.h>
+#include <xfs/xfs_icreate_item.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/include/xfs_ialloc.h b/include/xfs_ialloc.h
index c8da3df..68c0732 100644
--- a/include/xfs_ialloc.h
+++ b/include/xfs_ialloc.h
@@ -150,6 +150,14 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,
int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
xfs_inobt_rec_incore_t *rec, int *stat);
+/*
+ * Inode chunk initialisation routine
+ */
+int xfs_ialloc_inode_init(struct xfs_mount *mp, struct xfs_trans *tp,
+ struct list_head *buffer_list,
+ xfs_agnumber_t agno, xfs_agblock_t agbno,
+ xfs_agblock_t length, unsigned int gen);
+
extern const struct xfs_buf_ops xfs_agi_buf_ops;
#endif /* __XFS_IALLOC_H__ */
diff --git a/include/xfs_icreate_item.h b/include/xfs_icreate_item.h
index 88ba8aa..70dc03c 100644
--- a/include/xfs_icreate_item.h
+++ b/include/xfs_icreate_item.h
@@ -36,6 +36,8 @@ struct xfs_icreate_log {
__be32 icl_gen; /* inode generation number to use */
};
+#ifdef __KERNEL__
+
/* in memory log item structure */
struct xfs_icreate_item {
struct xfs_log_item ic_item;
@@ -48,5 +50,6 @@ void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno,
xfs_agblock_t agbno, unsigned int count,
unsigned int inode_size, xfs_agblock_t length,
unsigned int generation);
+#endif /* __KERNEL__ */
#endif /* XFS_ICREATE_ITEM_H */
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index aa71ecc..15e82d7 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -176,6 +176,7 @@ roundup_pow_of_two(uint v)
#define XBF_TRYLOCK XFS_BUF_TRYLOCK
#define XBF_DONT_BLOCK 0
#define XBF_UNMAPPED 0
+#define XBF_DONE 0
#define XFS_BUF_GETERROR(bp) 0
#define XFS_BUF_DONE(bp) ((bp)->b_flags |= LIBXFS_B_UPTODATE)
#define XFS_BUF_ISDONE(bp) ((bp)->b_flags & LIBXFS_B_UPTODATE)
@@ -194,6 +195,7 @@ roundup_pow_of_two(uint v)
#define xfs_buf_relse(bp) libxfs_putbuf(bp)
#define xfs_buf_get(devp,blkno,len,f) (libxfs_getbuf((devp), (blkno), (len)))
#define xfs_bwrite(bp) libxfs_writebuf((bp), 0)
+#define xfs_buf_delwri_queue(bp, bl) libxfs_writebuf((bp), 0)
#define XBRW_READ LIBXFS_BREAD
#define XBRW_WRITE LIBXFS_BWRITE
@@ -252,6 +254,7 @@ roundup_pow_of_two(uint v)
#define xfs_trans_get_block_res(tp) 1
#define xfs_trans_set_sync(tp) ((void) 0)
+#define xfs_trans_ordered_buf(tp, bp) ((void) 0)
#define xfs_trans_agblocks_delta(tp, d)
#define xfs_trans_agflist_delta(tp, d)
#define xfs_trans_agbtree_delta(tp, d)
@@ -325,6 +328,8 @@ do { \
#define uuid_copy(s,d) platform_uuid_copy((s),(d))
#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0)
+#define xfs_icreate_log(tp, agno, agbno, cnt, isize, len, gen) ((void) 0)
+
/*
* Prototypes for kernel static functions that are aren't in their
* associated header files
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 76fdcea..48916dd 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -129,12 +129,16 @@ xfs_check_agi_freecount(
#endif
/*
- * Initialise a new set of inodes.
+ * Initialise a new set of inodes. When called without a transaction context
+ * (e.g. from recovery) we initiate a delayed write of the inode buffers rather
+ * than logging them (which in a transaction context puts them into the AIL
+ * for writeback rather than the xfsbufd queue).
*/
-STATIC int
+int
xfs_ialloc_inode_init(
struct xfs_mount *mp,
struct xfs_trans *tp,
+ struct list_head *buffer_list,
xfs_agnumber_t agno,
xfs_agblock_t agbno,
xfs_agblock_t length,
@@ -165,22 +169,40 @@ xfs_ialloc_inode_init(
}
/*
- * Figure out what version number to use in the inodes we create.
- * If the superblock version has caught up to the one that supports
- * the new inode format, then use the new inode version. Otherwise
- * use the old version so that old kernels will continue to be
- * able to use the file system.
+ * Figure out what version number to use in the inodes we create. If
+ * the superblock version has caught up to the one that supports the new
+ * inode format, then use the new inode version. Otherwise use the old
+ * version so that old kernels will continue to be able to use the file
+ * system.
*
* For v3 inodes, we also need to write the inode number into the inode,
* so calculate the first inode number of the chunk here as
- * XFS_OFFBNO_TO_AGINO() only works on filesystem block boundaries, not
- * cluster boundaries and so cannot be used in the cluster buffer loop
- * below.
+ * XFS_OFFBNO_TO_AGINO() only works within a filesystem block, not
+ * across multiple filesystem blocks (such as a cluster) and so cannot
+ * be used in the cluster buffer loop below.
+ *
+ * Further, because we are writing the inode directly into the buffer
+ * and calculating a CRC on the entire inode, we have ot log the entire
+ * inode so that the entire range the CRC covers is present in the log.
+ * That means for v3 inode we log the entire buffer rather than just the
+ * inode cores.
*/
if (xfs_sb_version_hascrc(&mp->m_sb)) {
version = 3;
ino = XFS_AGINO_TO_INO(mp, agno,
XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
+
+ /*
+ * log the initialisation that is about to take place as an
+ * logical operation. This means the transaction does not
+ * need to log the physical changes to the inode buffers as log
+ * recovery will know what initialisation is actually needed.
+ * Hence we only need to log the buffers as "ordered" buffers so
+ * they track in the AIL as if they were physically logged.
+ */
+ if (tp)
+ xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
+ mp->m_sb.sb_inodesize, length, gen);
} else if (xfs_sb_version_hasnlink(&mp->m_sb))
version = 2;
else
@@ -196,15 +218,10 @@ xfs_ialloc_inode_init(
XBF_UNMAPPED);
if (!fbuf)
return ENOMEM;
- /*
- * Initialize all inodes in this buffer and then log them.
- *
- * XXX: It would be much better if we had just one transaction
- * to log a whole cluster of inodes instead of all the
- * individual transactions causing a lot of log traffic.
- */
+
+ /* Initialize the inode buffers and log them appropriately. */
fbuf->b_ops = &xfs_inode_buf_ops;
- xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
+ xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
for (i = 0; i < ninodes; i++) {
int ioffset = i << mp->m_sb.sb_inodelog;
uint isize = xfs_dinode_size(version);
@@ -220,11 +237,39 @@ xfs_ialloc_inode_init(
ino++;
uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid);
xfs_dinode_calc_crc(mp, free);
+ } else if (tp) {
+ /* just log the inode core */
+ xfs_trans_log_buf(tp, fbuf, ioffset,
+ ioffset + isize - 1);
}
+ }
- xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
+ if (tp) {
+ /*
+ * Mark the buffer as an inode allocation buffer so it
+ * sticks in AIL at the point of this allocation
+ * transaction. This ensures the they are on disk before
+ * the tail of the log can be moved past this
+ * transaction (i.e. by preventing relogging from moving
+ * it forward in the log).
+ */
+ xfs_trans_inode_alloc_buf(tp, fbuf);
+ if (version == 3) {
+ /*
+ * Mark the buffer as ordered so that they are
+ * not physically logged in the transaction but
+ * still tracked in the AIL as part of the
+ * transaction and pin the log appropriately.
+ */
+ xfs_trans_ordered_buf(tp, fbuf);
+ xfs_trans_log_buf(tp, fbuf, 0,
+ BBTOB(fbuf->b_length) - 1);
+ }
+ } else {
+ fbuf->b_flags |= XBF_DONE;
+ xfs_buf_delwri_queue(fbuf, buffer_list);
+ xfs_buf_relse(fbuf);
}
- xfs_trans_inode_alloc_buf(tp, fbuf);
}
return 0;
}
@@ -372,7 +417,7 @@ xfs_ialloc_ag_alloc(
* rather than a linear progression to prevent the next generation
* number from being easily guessable.
*/
- error = xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno,
+ error = xfs_ialloc_inode_init(args.mp, tp, NULL, agno, args.agbno,
args.len, prandom_u32());
if (error)
diff --git a/libxfs/xfs_trans.c b/libxfs/xfs_trans.c
index bdd0ebc..95fb630 100644
--- a/libxfs/xfs_trans.c
+++ b/libxfs/xfs_trans.c
@@ -208,71 +208,93 @@ xfs_calc_remove_reservation(
}
/*
- * For symlink we can modify:
+ * For create, break it in to the two cases that the transaction
+ * covers. We start with the modify case - allocation done by modification
+ * of the state of existing inodes - and the allocation case.
+ */
+
+/*
+ * For create we can modify:
* the parent directory inode: inode size
* the new inode: inode size
- * the inode btree entry: 1 block
+ * the inode btree entry: block size
+ * the superblock for the nlink flag: sector size
* the directory btree: (max depth + v2) * dir block size
* the directory inode's bmap btree: (max depth + v2) * block size
- * the blocks for the symlink: 1 kB
- * Or in the first xact we allocate some inodes giving:
+ */
+STATIC uint
+xfs_calc_create_resv_modify(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ (uint)XFS_FSB_TO_B(mp, 1) +
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * For create we can allocate some inodes giving:
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
* the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
* the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
*/
STATIC uint
-xfs_calc_symlink_reservation(
+xfs_calc_create_resv_alloc(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+ xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+STATIC uint
+__xfs_calc_create_reservation(
struct xfs_mount *mp)
{
return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(1, 1024)),
- (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(mp->m_in_maxlevels,
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1))));
+ MAX(xfs_calc_create_resv_alloc(mp),
+ xfs_calc_create_resv_modify(mp));
}
/*
- * For create we can modify:
- * the parent directory inode: inode size
- * the new inode: inode size
- * the inode btree entry: block size
- * the superblock for the nlink flag: sector size
- * the directory btree: (max depth + v2) * dir block size
- * the directory inode's bmap btree: (max depth + v2) * block size
- * Or in the first xact we allocate some inodes giving:
+ * For icreate we can allocate some inodes giving:
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
* the superblock for the nlink flag: sector size
- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
* the inode btree: max depth * blocksize
* the allocation btrees: 2 trees * (max depth - 1) * block size
*/
STATIC uint
-xfs_calc_create_reservation(
+xfs_calc_icreate_resv_alloc(
struct xfs_mount *mp)
{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+STATIC uint
+xfs_calc_icreate_reservation(xfs_mount_t *mp)
+{
return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
- XFS_FSB_TO_B(mp, 1) +
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- mp->m_sb.sb_sectsize +
- xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(mp->m_in_maxlevels,
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1))));
+ MAX(xfs_calc_icreate_resv_alloc(mp),
+ xfs_calc_create_resv_modify(mp));
+}
+
+STATIC uint
+xfs_calc_create_reservation(
+ struct xfs_mount *mp)
+{
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ return xfs_calc_icreate_reservation(mp);
+ return __xfs_calc_create_reservation(mp);
+
}
/*
@@ -285,6 +307,20 @@ xfs_calc_mkdir_reservation(
return xfs_calc_create_reservation(mp);
}
+
+/*
+ * Making a new symplink is the same as creating a new file, but
+ * with the added blocks for remote symlink data which can be up to 1kB in
+ * length (MAXPATHLEN).
+ */
+STATIC uint
+xfs_calc_symlink_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_create_reservation(mp) +
+ xfs_calc_buf_res(1, MAXPATHLEN);
+}
+
/*
* In freeing an inode we can modify:
* the inode being freed: inode size
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 03/49] xfsprogs: teach logprint about icreate transaction
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
2013-07-19 6:44 ` [PATCH 01/49] xfsprogs: introduce xfs_icreate.h Dave Chinner
2013-07-19 6:44 ` [PATCH 02/49] xfsprogs: port inode create transaction changes Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-01 21:30 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 04/49] libxfs: fix directory/attribute format issues Dave Chinner
` (46 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxlog.h | 1 +
logprint/log_misc.c | 36 ++++++++++++++++++++++++++++++++++++
logprint/log_print_all.c | 21 +++++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/include/libxlog.h b/include/libxlog.h
index bd71bfe..ff711e9 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -51,6 +51,7 @@ struct xlog {
#include <xfs/xfs_buf_item.h>
#include <xfs/xfs_inode_item.h>
#include <xfs/xfs_extfree_item.h>
+#include <xfs/xfs_icreate_item.h>
typedef union {
xlog_rec_header_t hic_header;
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 7012208..9526ec4 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -70,6 +70,7 @@ char *trans_type[] = {
"SWAPEXT",
"SB_COUNT",
"CHECKPOINT",
+ "ICREATE",
};
typedef struct xlog_split_item {
@@ -792,6 +793,35 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
} /* xlog_print_trans_dquot */
+STATIC int
+xlog_print_trans_icreate(
+ xfs_caddr_t *ptr,
+ int len,
+ int *i,
+ int num_ops)
+{
+ struct xfs_icreate_log icl_buf = {0};
+ struct xfs_icreate_log *icl;
+
+ memmove(&icl_buf, *ptr, MIN(sizeof(struct xfs_icreate_log), len));
+ icl = &icl_buf;
+ (*i)++;
+ *ptr += len;
+
+ /* handle complete header only */
+ if (len != sizeof(struct xfs_icreate_log)) {
+ printf(_("ICR: split header, not printing\n"));
+ return 1; /* to skip leftover in next region */
+ }
+
+ printf(_("ICR: #ag: %d agbno: 0x%x len: %d\n"
+ " cnt: %d isize: %d gen: 0x%x\n"),
+ be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno),
+ be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count),
+ be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen));
+ return 0;
+}
+
/******************************************************************************
*
* Log print routines
@@ -974,6 +1004,12 @@ xlog_print_record(int fd,
&i, num_ops);
break;
}
+ case XFS_LI_ICREATE: {
+ skip = xlog_print_trans_icreate(&ptr,
+ be32_to_cpu(op_head->oh_len),
+ &i, num_ops);
+ break;
+ }
case XFS_LI_INODE: {
skip = xlog_print_trans_inode(&ptr,
be32_to_cpu(op_head->oh_len),
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 4626186..7f87016 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -435,6 +435,21 @@ xlog_recover_print_efi(
free(f);
}
+STATIC void
+xlog_recover_print_icreate(
+ struct xlog_recover_item *item)
+{
+ struct xfs_icreate_log *icl;
+
+ icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
+
+ printf(_(" ICR: #ag: %d agbno: 0x%x len: %d\n"
+ " cnt: %d isize: %d gen: 0x%x\n"),
+ be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno),
+ be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count),
+ be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen));
+}
+
void
xlog_recover_print_logitem(
xlog_recover_item_t *item)
@@ -443,6 +458,9 @@ xlog_recover_print_logitem(
case XFS_LI_BUF:
xlog_recover_print_buffer(item);
break;
+ case XFS_LI_ICREATE:
+ xlog_recover_print_icreate(item);
+ break;
case XFS_LI_INODE:
xlog_recover_print_inode(item);
break;
@@ -474,6 +492,9 @@ xlog_recover_print_item(
case XFS_LI_BUF:
printf("BUF");
break;
+ case XFS_LI_ICREATE:
+ printf("ICR");
+ break;
case XFS_LI_INODE:
printf("INO");
break;
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 04/49] libxfs: fix directory/attribute format issues
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (2 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 03/49] xfsprogs: teach logprint about icreate transaction Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 13:10 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly Dave Chinner
` (45 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
directory data headers and attr leaf headers need padding for 32 bit
systems to correctly align the data sections on 64 bit boundaries.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_attr_leaf.h | 1 +
include/xfs_dir2_format.h | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/xfs_attr_leaf.h b/include/xfs_attr_leaf.h
index b3e93bb..c102213 100644
--- a/include/xfs_attr_leaf.h
+++ b/include/xfs_attr_leaf.h
@@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr {
__u8 holes;
__u8 pad1;
struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
+ __be32 pad2; /* 64 bit alignment */
};
#define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc))
diff --git a/include/xfs_dir2_format.h b/include/xfs_dir2_format.h
index 8c16bb0..4126e86 100644
--- a/include/xfs_dir2_format.h
+++ b/include/xfs_dir2_format.h
@@ -260,6 +260,7 @@ struct xfs_dir3_blk_hdr {
struct xfs_dir3_data_hdr {
struct xfs_dir3_blk_hdr hdr;
xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT];
+ __be32 pad; /* 64 bit alignment */
};
#define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc)
@@ -471,7 +472,7 @@ struct xfs_dir3_leaf_hdr {
struct xfs_da3_blkinfo info; /* header for da routines */
__be16 count; /* count of entries */
__be16 stale; /* count of stale entries */
- __be32 pad;
+ __be32 pad; /* 64 bit alignment */
};
struct xfs_dir3_icleaf_hdr {
@@ -712,7 +713,7 @@ struct xfs_dir3_free_hdr {
__be32 firstdb; /* db of first entry */
__be32 nvalid; /* count of valid entries */
__be32 nused; /* count of used entries */
- __be32 pad; /* 64 bit alignment. */
+ __be32 pad; /* 64 bit alignment */
};
struct xfs_dir3_free {
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (3 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 04/49] libxfs: fix directory/attribute format issues Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 13:12 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 06/49] libxfs: fix byte swapping on constants Dave Chinner
` (44 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
For CRC enabled filesystems, the BMBT is rooted in an inode, so it
passes through a difference code path on root splits to the
freespace and inode btrees. The inode based btree root has a
corruption problem on split - it's the same problem we saw in the
directory/attr code where headers are memcpy()d from one block to
another without updating the self describing metadata.
Simple fix - when copying the header out of the root block, make
sure the block number is updated correctly.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_btree.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index b11131c..3ac3330 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -2487,7 +2487,17 @@ xfs_btree_new_iroot(
if (error)
goto error0;
+ /*
+ * we can't just memcpy() the root in for CRC enabled btree blocks.
+ * In that case have to also ensure the blkno remains correct
+ */
memcpy(cblock, block, xfs_btree_block_len(cur));
+ if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
+ if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn);
+ else
+ cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn);
+ }
be16_add_cpu(&block->bb_level, 1);
xfs_btree_set_numrecs(block, 1);
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 06/49] libxfs: fix byte swapping on constants
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (4 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 13:51 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 07/49] libxfs: sync xfs_da_btree.c Dave Chinner
` (43 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The kernel code uses cpu_to_beXX() on constants in switch()
statements for magic numbers in the btree code. Th ebyte swapping
infratructure isn't hooked up to the proper byte swap macros to make
this work, so fix it and then swap all the generic btree code over
to match the kernel code.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/swab.h | 6 +++---
libxfs/xfs_alloc_btree.c | 23 ++++++++++++++---------
libxfs/xfs_bmap_btree.c | 14 ++++++--------
libxfs/xfs_ialloc_btree.c | 16 +++++++++++-----
4 files changed, 34 insertions(+), 25 deletions(-)
diff --git a/include/swab.h b/include/swab.h
index 3de44d8..b06346c 100644
--- a/include/swab.h
+++ b/include/swab.h
@@ -96,15 +96,15 @@
*/
# define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
- ___swab16((x)) : \
+ ___constant_swab16((x)) : \
__fswab16((x)))
# define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
- ___swab32((x)) : \
+ ___constant_swab32((x)) : \
__fswab32((x)))
# define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
- ___swab64((x)) : \
+ ___constant_swab64((x)) : \
__fswab64((x)))
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 1ee1f48..282a320 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -268,10 +268,15 @@ xfs_allocbt_verify(
* During growfs operations, we can't verify the exact level or owner as
* the perag is not fully initialised and hence not attached to the
* buffer. In this case, check against the maximum tree depth.
+ *
+ * Similarly, during log recovery we will have a perag structure
+ * attached, but the agf information will not yet have been initialised
+ * from the on disk AGF. Again, we can only check against maximum limits
+ * in this case.
*/
level = be16_to_cpu(block->bb_level);
- switch (cpu_to_be32(block->bb_magic)) {
- case XFS_ABTB_CRC_MAGIC:
+ switch (block->bb_magic) {
+ case cpu_to_be32(XFS_ABTB_CRC_MAGIC):
if (!xfs_sb_version_hascrc(&mp->m_sb))
return false;
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
@@ -282,14 +287,14 @@ xfs_allocbt_verify(
be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
return false;
/* fall through */
- case XFS_ABTB_MAGIC:
- if (pag) {
+ case cpu_to_be32(XFS_ABTB_MAGIC):
+ if (pag && pag->pagf_init) {
if (level >= pag->pagf_levels[XFS_BTNUM_BNOi])
return false;
} else if (level >= mp->m_ag_maxlevels)
return false;
break;
- case XFS_ABTC_CRC_MAGIC:
+ case cpu_to_be32(XFS_ABTC_CRC_MAGIC):
if (!xfs_sb_version_hascrc(&mp->m_sb))
return false;
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
@@ -300,8 +305,8 @@ xfs_allocbt_verify(
be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
return false;
/* fall through */
- case XFS_ABTC_MAGIC:
- if (pag) {
+ case cpu_to_be32(XFS_ABTC_MAGIC):
+ if (pag && pag->pagf_init) {
if (level >= pag->pagf_levels[XFS_BTNUM_CNTi])
return false;
} else if (level >= mp->m_ag_maxlevels)
@@ -361,7 +366,7 @@ const struct xfs_buf_ops xfs_allocbt_buf_ops = {
};
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
STATIC int
xfs_allocbt_keys_inorder(
struct xfs_btree_cur *cur,
@@ -483,7 +488,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {
.init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
.key_diff = xfs_allocbt_key_diff,
.buf_ops = &xfs_allocbt_buf_ops,
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
.keys_inorder = xfs_allocbt_keys_inorder,
.recs_inorder = xfs_allocbt_recs_inorder,
#endif
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 473db4a..bf214cf 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -708,13 +708,13 @@ xfs_bmbt_verify(
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
unsigned int level;
- switch (be32_to_cpu(block->bb_magic)) {
- case XFS_BMAP_CRC_MAGIC:
+ switch (block->bb_magic) {
+ case cpu_to_be32(XFS_BMAP_CRC_MAGIC):
if (!xfs_sb_version_hascrc(&mp->m_sb))
return false;
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid))
return false;
- if (block->bb_u.l.bb_blkno != cpu_to_be64(bp->b_bn))
+ if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn)
return false;
/*
* XXX: need a better way of verifying the owner here. Right now
@@ -723,7 +723,7 @@ xfs_bmbt_verify(
if (be64_to_cpu(block->bb_u.l.bb_owner) == 0)
return false;
/* fall through */
- case XFS_BMAP_MAGIC:
+ case cpu_to_be32(XFS_BMAP_MAGIC):
break;
default:
return false;
@@ -759,7 +759,6 @@ static void
xfs_bmbt_read_verify(
struct xfs_buf *bp)
{
- xfs_bmbt_verify(bp);
if (!(xfs_btree_lblock_verify_crc(bp) &&
xfs_bmbt_verify(bp))) {
trace_xfs_btree_corrupt(bp, _RET_IP_);
@@ -767,7 +766,6 @@ xfs_bmbt_read_verify(
bp->b_target->bt_mount, bp->b_addr);
xfs_buf_ioerror(bp, EFSCORRUPTED);
}
-
}
static void
@@ -791,7 +789,7 @@ const struct xfs_buf_ops xfs_bmbt_buf_ops = {
};
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
STATIC int
xfs_bmbt_keys_inorder(
struct xfs_btree_cur *cur,
@@ -920,7 +918,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
.init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
.key_diff = xfs_bmbt_key_diff,
.buf_ops = &xfs_bmbt_buf_ops,
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
.keys_inorder = xfs_bmbt_keys_inorder,
.recs_inorder = xfs_bmbt_recs_inorder,
#endif
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index ee036bf..27a5dd9 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -175,9 +175,15 @@ xfs_inobt_verify(
/*
* During growfs operations, we can't verify the exact owner as the
* perag is not fully initialised and hence not attached to the buffer.
+ *
+ * Similarly, during log recovery we will have a perag structure
+ * attached, but the agi information will not yet have been initialised
+ * from the on disk AGI. We don't currently use any of this information,
+ * but beware of the landmine (i.e. need to check pag->pagi_init) if we
+ * ever do.
*/
- switch (be32_to_cpu(block->bb_magic)) {
- case XFS_IBT_CRC_MAGIC:
+ switch (block->bb_magic) {
+ case cpu_to_be32(XFS_IBT_CRC_MAGIC):
if (!xfs_sb_version_hascrc(&mp->m_sb))
return false;
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
@@ -188,7 +194,7 @@ xfs_inobt_verify(
be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
return false;
/* fall through */
- case XFS_IBT_MAGIC:
+ case cpu_to_be32(XFS_IBT_MAGIC):
break;
default:
return 0;
@@ -246,7 +252,7 @@ const struct xfs_buf_ops xfs_inobt_buf_ops = {
.verify_write = xfs_inobt_write_verify,
};
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
STATIC int
xfs_inobt_keys_inorder(
struct xfs_btree_cur *cur,
@@ -350,7 +356,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
.init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
.key_diff = xfs_inobt_key_diff,
.buf_ops = &xfs_inobt_buf_ops,
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
.keys_inorder = xfs_inobt_keys_inorder,
.recs_inorder = xfs_inobt_recs_inorder,
#endif
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 07/49] libxfs: sync xfs_da_btree.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (5 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 06/49] libxfs: fix byte swapping on constants Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 14:22 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 08/49] libxfs: update xfs_alloc to current kernel version Dave Chinner
` (42 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Some variables we renamed in the kernel code, and there are a few
other minor differences. Fix them up.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_da_btree.c | 63 +++++++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 30 deletions(-)
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index e83a3ad..d7798af 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -480,8 +480,10 @@ xfs_da3_split(
* There might be three blocks involved if a double split occurred,
* and the original block 0 could be at any position in the list.
*
- * Note: the info structures being modified here for both v2 and v3 da
- * headers, so we can do this linkage just using the v2 structures.
+ * Note: the magic numbers and sibling pointers are in the same
+ * physical place for both v2 and v3 headers (by design). Hence it
+ * doesn't matter which version of the xfs_da_intnode structure we use
+ * here as the result will be the same using either structure.
*/
node = oldblk->bp->b_addr;
if (node->hdr.info.forw) {
@@ -820,7 +822,7 @@ xfs_da3_node_rebalance(
*/
nodehdr2.count += count;
tmp = count * (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &btree1[nodehdr1.count- count];
+ btree_s = &btree1[nodehdr1.count - count];
btree_d = &btree2[0];
memcpy(btree_d, btree_s, tmp);
nodehdr1.count -= count;
@@ -1380,10 +1382,10 @@ xfs_da3_node_unbalance(
{
struct xfs_da_intnode *drop_node;
struct xfs_da_intnode *save_node;
- struct xfs_da_node_entry *dbtree;
- struct xfs_da_node_entry *sbtree;
- struct xfs_da3_icnode_hdr dhdr;
- struct xfs_da3_icnode_hdr shdr;
+ struct xfs_da_node_entry *drop_btree;
+ struct xfs_da_node_entry *save_btree;
+ struct xfs_da3_icnode_hdr drop_hdr;
+ struct xfs_da3_icnode_hdr save_hdr;
struct xfs_trans *tp;
int sindex;
int tmp;
@@ -1392,43 +1394,44 @@ xfs_da3_node_unbalance(
drop_node = drop_blk->bp->b_addr;
save_node = save_blk->bp->b_addr;
- xfs_da3_node_hdr_from_disk(&dhdr, drop_node);
- xfs_da3_node_hdr_from_disk(&shdr, save_node);
- dbtree = xfs_da3_node_tree_p(drop_node);
- sbtree = xfs_da3_node_tree_p(save_node);
+ xfs_da3_node_hdr_from_disk(&drop_hdr, drop_node);
+ xfs_da3_node_hdr_from_disk(&save_hdr, save_node);
+ drop_btree = xfs_da3_node_tree_p(drop_node);
+ save_btree = xfs_da3_node_tree_p(save_node);
tp = state->args->trans;
/*
* If the dying block has lower hashvals, then move all the
* elements in the remaining block up to make a hole.
*/
- if ((be32_to_cpu(dbtree[0].hashval) < be32_to_cpu(sbtree[ 0 ].hashval)) ||
- (be32_to_cpu(dbtree[dhdr.count - 1].hashval) <
- be32_to_cpu(sbtree[shdr.count - 1].hashval))) {
+ if ((be32_to_cpu(drop_btree[0].hashval) <
+ be32_to_cpu(save_btree[0].hashval)) ||
+ (be32_to_cpu(drop_btree[drop_hdr.count - 1].hashval) <
+ be32_to_cpu(save_btree[save_hdr.count - 1].hashval))) {
/* XXX: check this - is memmove dst correct? */
- tmp = shdr.count * (uint)sizeof(xfs_da_node_entry_t);
- memmove(&sbtree[dhdr.count], &sbtree[0], tmp);
+ tmp = save_hdr.count * sizeof(xfs_da_node_entry_t);
+ memmove(&save_btree[drop_hdr.count], &save_btree[0], tmp);
sindex = 0;
xfs_trans_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, &sbtree[0],
- (shdr.count + dhdr.count) *
+ XFS_DA_LOGRANGE(save_node, &save_btree[0],
+ (save_hdr.count + drop_hdr.count) *
sizeof(xfs_da_node_entry_t)));
} else {
- sindex = shdr.count;
+ sindex = save_hdr.count;
xfs_trans_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, &sbtree[sindex],
- dhdr.count * sizeof(xfs_da_node_entry_t)));
+ XFS_DA_LOGRANGE(save_node, &save_btree[sindex],
+ drop_hdr.count * sizeof(xfs_da_node_entry_t)));
}
/*
* Move all the B-tree elements from drop_blk to save_blk.
*/
- tmp = dhdr.count * (uint)sizeof(xfs_da_node_entry_t);
- memcpy(&sbtree[sindex], &dbtree[0], tmp);
- shdr.count += dhdr.count;
+ tmp = drop_hdr.count * (uint)sizeof(xfs_da_node_entry_t);
+ memcpy(&save_btree[sindex], &drop_btree[0], tmp);
+ save_hdr.count += drop_hdr.count;
- xfs_da3_node_hdr_to_disk(save_node, &shdr);
+ xfs_da3_node_hdr_to_disk(save_node, &save_hdr);
xfs_trans_log_buf(tp, save_blk->bp,
XFS_DA_LOGRANGE(save_node, &save_node->hdr,
xfs_da3_node_hdr_size(save_node)));
@@ -1436,7 +1439,7 @@ xfs_da3_node_unbalance(
/*
* Save the last hashval in the remaining block for upward propagation.
*/
- save_blk->hashval = be32_to_cpu(sbtree[shdr.count - 1].hashval);
+ save_blk->hashval = be32_to_cpu(save_btree[save_hdr.count - 1].hashval);
}
/*========================================================================
@@ -2201,8 +2204,6 @@ xfs_da3_swap_lastblock(
} else {
struct xfs_da3_icnode_hdr deadhdr;
- ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
- dead_info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
dead_node = (xfs_da_intnode_t *)dead_info;
xfs_da3_node_hdr_from_disk(&deadhdr, dead_node);
btree = xfs_da3_node_tree_p(dead_node);
@@ -2441,7 +2442,8 @@ xfs_buf_map_from_irec(
ASSERT(nirecs >= 1);
if (nirecs > 1) {
- map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP);
+ map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),
+ KM_SLEEP | KM_NOFS);
if (!map)
return ENOMEM;
*mapp = map;
@@ -2497,7 +2499,8 @@ xfs_dabuf_map(
* Optimize the one-block case.
*/
if (nfsb != 1)
- irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP);
+ irecs = kmem_zalloc(sizeof(irec) * nfsb,
+ KM_SLEEP | KM_NOFS);
nirecs = nfsb;
error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 08/49] libxfs: update xfs_alloc to current kernel version
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (6 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 07/49] libxfs: sync xfs_da_btree.c Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 15:11 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 09/49] libxfs: sync attr code with kernel Dave Chinner
` (41 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_alloc.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 1d7ea8f..757b43d 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -153,6 +153,7 @@ xfs_alloc_compute_diff(
xfs_agblock_t wantbno, /* target starting block */
xfs_extlen_t wantlen, /* target length */
xfs_extlen_t alignment, /* target alignment */
+ char userdata, /* are we allocating data? */
xfs_agblock_t freebno, /* freespace's starting block */
xfs_extlen_t freelen, /* freespace's length */
xfs_agblock_t *newbnop) /* result: best start block from free */
@@ -167,7 +168,14 @@ xfs_alloc_compute_diff(
ASSERT(freelen >= wantlen);
freeend = freebno + freelen;
wantend = wantbno + wantlen;
- if (freebno >= wantbno) {
+ /*
+ * We want to allocate from the start of a free extent if it is past
+ * the desired block or if we are allocating user data and the free
+ * extent is before desired block. The second case is there to allow
+ * for contiguous allocation from the remaining free space if the file
+ * grows in the short term.
+ */
+ if (freebno >= wantbno || (userdata && freeend < wantend)) {
if ((newbno1 = roundup(freebno, alignment)) >= freeend)
newbno1 = NULLAGBLOCK;
} else if (freeend >= wantend && alignment > 1) {
@@ -783,7 +791,8 @@ xfs_alloc_find_best_extent(
xfs_alloc_fix_len(args);
sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
- args->alignment, *sbnoa,
+ args->alignment,
+ args->userdata, *sbnoa,
*slena, &new);
/*
@@ -954,7 +963,8 @@ restart:
if (args->len < blen)
continue;
ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
- args->alignment, ltbnoa, ltlena, <new);
+ args->alignment, args->userdata, ltbnoa,
+ ltlena, <new);
if (ltnew != NULLAGBLOCK &&
(args->len > blen || ltdiff < bdiff)) {
bdiff = ltdiff;
@@ -1106,7 +1116,8 @@ restart:
args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
xfs_alloc_fix_len(args);
ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
- args->alignment, ltbnoa, ltlena, <new);
+ args->alignment, args->userdata, ltbnoa,
+ ltlena, <new);
error = xfs_alloc_find_best_extent(args,
&bno_cur_lt, &bno_cur_gt,
@@ -1122,7 +1133,8 @@ restart:
args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
xfs_alloc_fix_len(args);
gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
- args->alignment, gtbnoa, gtlena, >new);
+ args->alignment, args->userdata, gtbnoa,
+ gtlena, >new);
error = xfs_alloc_find_best_extent(args,
&bno_cur_gt, &bno_cur_lt,
@@ -1181,7 +1193,7 @@ restart:
}
rlen = args->len;
(void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
- ltbnoa, ltlena, <new);
+ args->userdata, ltbnoa, ltlena, <new);
ASSERT(ltnew >= ltbno);
ASSERT(ltnew + rlen <= ltbnoa + ltlena);
ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
@@ -2173,13 +2185,8 @@ xfs_agf_verify(
struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
if (xfs_sb_version_hascrc(&mp->m_sb) &&
- !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_uuid)) {
- char uu[64], uu2[64];
- platform_uuid_unparse(&agf->agf_uuid, uu);
- platform_uuid_unparse(&mp->m_sb.sb_uuid, uu2);
-
+ !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_uuid))
return false;
- }
if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 09/49] libxfs: sync attr code with kernel
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (7 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 08/49] libxfs: update xfs_alloc to current kernel version Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 16:02 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 10/49] libxfs: sync dir2 kernel differences Dave Chinner
` (40 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_attr.c | 6 +++---
libxfs/xfs_attr_leaf.c | 7 +++----
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index cfc2f4b..8fe892e 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -65,7 +65,7 @@ xfs_attr_name_to_xname(
return 0;
}
-STATIC int
+int
xfs_inode_hasattr(
struct xfs_inode *ip)
{
@@ -268,7 +268,6 @@ xfs_attr_set_int(
if (rsvd)
args.trans->t_flags |= XFS_TRANS_RESERVE;
-
error = xfs_trans_reserve(args.trans, args.total,
XFS_ATTRSETM_LOG_RES(mp) +
XFS_ATTRSETRT_LOG_RES(mp) * args.total,
@@ -587,6 +586,7 @@ xfs_attr_remove(
return xfs_attr_remove_int(dp, &xname, flags);
}
+
/*========================================================================
* External routines when attribute list is inside the inode
*========================================================================*/
@@ -854,7 +854,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
error = xfs_attr3_leaf_lookup_int(bp, args);
if (error == ENOATTR) {
xfs_trans_brelse(args->trans, bp);
- return(error);
+ return error;
}
xfs_attr3_leaf_remove(bp, args);
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 4e2951b..49a1764 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -51,7 +51,6 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
int *number_entries_in_blk1,
int *number_usedbytes_in_blk1);
-
/*
* Utility routines.
*/
@@ -1120,7 +1119,6 @@ xfs_attr3_leaf_add_work(
struct xfs_attr_leaf_entry *entry;
struct xfs_attr_leaf_name_local *name_loc;
struct xfs_attr_leaf_name_remote *name_rmt;
- struct xfs_attr_leaf_map *map;
struct xfs_mount *mp;
int tmp;
int i;
@@ -1219,7 +1217,7 @@ xfs_attr3_leaf_add_work(
tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
+ xfs_attr3_leaf_hdr_size(leaf);
- for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
+ for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
if (ichdr->freemap[i].base == tmp) {
ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
ichdr->freemap[i].size -= sizeof(xfs_attr_leaf_entry_t);
@@ -2337,7 +2335,7 @@ xfs_attr3_leaf_moveents(
* Move the remaining entries down to fill the hole,
* then zero the entries at the top.
*/
- tmp = (ichdr_s->count - count) - sizeof(xfs_attr_leaf_entry_t);
+ tmp = (ichdr_s->count - count) * sizeof(xfs_attr_leaf_entry_t);
entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s + count];
entry_d = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
memmove(entry_d, entry_s, tmp);
@@ -2431,6 +2429,7 @@ xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
return size;
}
+
/*========================================================================
* Manage the INCOMPLETE flag in a leaf entry
*========================================================================*/
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 10/49] libxfs: sync dir2 kernel differences
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (8 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 09/49] libxfs: sync attr code with kernel Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 16:25 ` Mark Tinguely
2013-08-08 22:04 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code Dave Chinner
` (39 subsequent siblings)
49 siblings, 2 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_dir2.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_dir2_data.c | 20 ++++++++++----------
libxfs/xfs_dir2_leaf.c | 4 ++--
libxfs/xfs_dir2_node.c | 30 ++++++++++++++----------------
4 files changed, 71 insertions(+), 28 deletions(-)
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 6a4027f..830fe3e 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -392,6 +392,51 @@ xfs_dir_replace(
}
/*
+ * See if this entry can be added to the directory without allocating space.
+ * First checks that the caller couldn't reserve enough space (resblks = 0).
+ */
+int
+xfs_dir_canenter(
+ xfs_trans_t *tp,
+ xfs_inode_t *dp,
+ struct xfs_name *name, /* name of entry to add */
+ uint resblks)
+{
+ xfs_da_args_t args;
+ int rval;
+ int v; /* type-checking value */
+
+ if (resblks)
+ return 0;
+
+ ASSERT(S_ISDIR(dp->i_d.di_mode));
+
+ memset(&args, 0, sizeof(xfs_da_args_t));
+ args.name = name->name;
+ args.namelen = name->len;
+ args.hashval = dp->i_mount->m_dirnameops->hashname(name);
+ args.dp = dp;
+ args.whichfork = XFS_DATA_FORK;
+ args.trans = tp;
+ args.op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME |
+ XFS_DA_OP_OKNOENT;
+
+ if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
+ rval = xfs_dir2_sf_addname(&args);
+ else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
+ return rval;
+ else if (v)
+ rval = xfs_dir2_block_addname(&args);
+ else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
+ return rval;
+ else if (v)
+ rval = xfs_dir2_leaf_addname(&args);
+ else
+ rval = xfs_dir2_node_addname(&args);
+ return rval;
+}
+
+/*
* Utility routines.
*/
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index 155352c..064ddb2 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -53,15 +53,15 @@ __xfs_dir3_data_check(
bf = xfs_dir3_data_bestfree_p(hdr);
p = (char *)xfs_dir3_data_entry_p(hdr);
- switch (be32_to_cpu(hdr->magic)) {
- case XFS_DIR2_BLOCK_MAGIC:
- case XFS_DIR3_BLOCK_MAGIC:
+ switch (hdr->magic) {
+ case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
+ case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
btp = xfs_dir2_block_tail_p(mp, hdr);
lep = xfs_dir2_block_leaf_p(btp);
endp = (char *)lep;
break;
- case XFS_DIR2_DATA_MAGIC:
- case XFS_DIR3_DATA_MAGIC:
+ case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
+ case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
endp = (char *)hdr + mp->m_dirblksize;
break;
default:
@@ -209,14 +209,14 @@ xfs_dir3_data_reada_verify(
struct xfs_mount *mp = bp->b_target->bt_mount;
struct xfs_dir2_data_hdr *hdr = bp->b_addr;
- switch (be32_to_cpu(hdr->magic)) {
- case XFS_DIR2_BLOCK_MAGIC:
- case XFS_DIR3_BLOCK_MAGIC:
+ switch (hdr->magic) {
+ case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
+ case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
bp->b_ops = &xfs_dir3_block_buf_ops;
bp->b_ops->verify_read(bp);
return;
- case XFS_DIR2_DATA_MAGIC:
- case XFS_DIR3_DATA_MAGIC:
+ case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
+ case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
xfs_dir3_data_verify(bp);
return;
default:
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index a287bb1..8c20b9e 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -247,14 +247,14 @@ xfs_dir3_leaf1_write_verify(
__write_verify(bp, XFS_DIR2_LEAF1_MAGIC);
}
-void
+static void
xfs_dir3_leafn_read_verify(
struct xfs_buf *bp)
{
__read_verify(bp, XFS_DIR2_LEAFN_MAGIC);
}
-void
+static void
xfs_dir3_leafn_write_verify(
struct xfs_buf *bp)
{
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index bdce1b3..222f08c 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -257,7 +257,6 @@ xfs_dir3_free_get_buf(
hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);
hdr3->hdr.owner = cpu_to_be64(dp->i_ino);
uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid);
-
} else
hdr.magic = XFS_DIR2_FREE_MAGIC;
xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr);
@@ -978,7 +977,7 @@ xfs_dir2_leafn_rebalance(
xfs_dir2_leaf_t *leaf1; /* first leaf structure */
xfs_dir2_leaf_t *leaf2; /* second leaf structure */
int mid; /* midpoint leaf index */
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
int oldstale; /* old count of stale leaves */
#endif
int oldsum; /* old total leaf count */
@@ -1007,7 +1006,7 @@ xfs_dir2_leafn_rebalance(
ents2 = xfs_dir3_leaf_ents_p(leaf2);
oldsum = hdr1.count + hdr2.count;
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
oldstale = hdr1.stale + hdr2.stale;
#endif
mid = oldsum >> 1;
@@ -1101,7 +1100,6 @@ xfs_dir3_data_block_free(
__be16 *bests;
struct xfs_dir3_icfree_hdr freehdr;
-
xfs_dir3_free_hdr_from_disk(&freehdr, free);
bests = xfs_dir3_free_bests_p(tp->t_mountp, free);
@@ -1115,12 +1113,14 @@ xfs_dir3_data_block_free(
return 0;
}
- /*
- * One less used entry in the free table. Unused is not converted
- * because we only need to know if it zero
- */
+ /* One less used entry in the free table. */
freehdr.nused--;
+ /*
+ * If this was the last entry in the table, we can trim the table size
+ * back. There might be other entries at the end referring to
+ * non-existent data blocks, get those too.
+ */
if (findex == freehdr.nvalid - 1) {
int i; /* free entry index */
@@ -1159,7 +1159,6 @@ xfs_dir3_data_block_free(
*/
}
-
/* Log the free entry that changed, unless we got rid of it. */
if (logfree)
xfs_dir2_free_log_bests(tp, fbp, findex, findex);
@@ -1275,9 +1274,8 @@ xfs_dir2_leafn_remove(
{
struct xfs_dir3_icfree_hdr freehdr;
xfs_dir3_free_hdr_from_disk(&freehdr, free);
- ASSERT(freehdr.firstdb ==
- xfs_dir3_free_max_bests(mp) *
- (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
+ ASSERT(freehdr.firstdb == xfs_dir3_free_max_bests(mp) *
+ (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
}
#endif
/*
@@ -1425,7 +1423,7 @@ xfs_dir2_leafn_toosmall(
leaf = blk->bp->b_addr;
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
ents = xfs_dir3_leaf_ents_p(leaf);
- xfs_dir3_leaf_check(mp, blk->bp);
+ xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp);
count = leafhdr.count - leafhdr.stale;
bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]);
@@ -1795,9 +1793,9 @@ xfs_dir2_node_addname_int(
/*
* Look at the current free entry. Is it good enough?
*
- * The bests initialisation should be wher eteh bufer is read in
+ * The bests initialisation should be where the bufer is read in
* the above branch. But gcc is too stupid to realise that bests
- * iand the freehdr are actually initialised if they are placed
+ * and the freehdr are actually initialised if they are placed
* there, so we have to do it here to avoid warnings. Blech.
*/
bests = xfs_dir3_free_bests_p(mp, free);
@@ -1863,7 +1861,7 @@ xfs_dir2_node_addname_int(
* If there wasn't a freespace block, the read will
* return a NULL fbp. Allocate and initialize a new one.
*/
- if(!fbp) {
+ if (!fbp) {
error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
&fbno);
if (error)
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (9 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 10/49] libxfs: sync dir2 kernel differences Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 18:08 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 12/49] xfsprogs: define min/max once and use them everywhere Dave Chinner
` (38 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
include the missing xfs_difree() function. it's not used by
userspace, but it makes no sense to have just this one arbitrary
difference between the kernel and userspace files.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs.h | 1 +
libxfs/xfs_ialloc.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 177 insertions(+), 10 deletions(-)
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 15e82d7..3fd226c 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -208,6 +208,7 @@ roundup_pow_of_two(uint v)
#define XFS_MOUNT_SMALL_INUMS 0 /* ignored in userspace */
#define XFS_MOUNT_WSYNC 0 /* ignored in userspace */
#define XFS_MOUNT_NOALIGN 0 /* ignored in userspace */
+#define XFS_MOUNT_IKEEP 0 /* ignored in userspace */
#define xfs_icsb_modify_counters(mp, field, delta, rsvd) \
xfs_mod_incore_sb(mp, field, delta, rsvd)
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 48916dd..98513fd 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -314,7 +314,7 @@ xfs_ialloc_ag_alloc(
* First try to allocate inodes contiguous with the last-allocated
* chunk of inodes. If the filesystem is striped, this will fill
* an entire stripe unit with inodes.
- */
+ */
agi = XFS_BUF_TO_AGI(agbp);
newino = be32_to_cpu(agi->agi_newino);
agno = be32_to_cpu(agi->agi_seqno);
@@ -324,8 +324,6 @@ xfs_ialloc_ag_alloc(
(args.agbno < be32_to_cpu(agi->agi_length)))) {
args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
args.type = XFS_ALLOCTYPE_THIS_BNO;
- args.mod = args.total = args.wasdel = args.isfl =
- args.userdata = args.minalignslop = 0;
args.prod = 1;
/*
@@ -378,8 +376,6 @@ xfs_ialloc_ag_alloc(
* Allocate a fixed-size extent of inodes.
*/
args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.mod = args.total = args.wasdel = args.isfl =
- args.userdata = args.minalignslop = 0;
args.prod = 1;
/*
* Allow space for the inode btree to split.
@@ -630,8 +626,7 @@ xfs_ialloc_get_rec(
struct xfs_btree_cur *cur,
xfs_agino_t agino,
xfs_inobt_rec_incore_t *rec,
- int *done,
- int left)
+ int *done)
{
int error;
int i;
@@ -739,12 +734,12 @@ xfs_dialloc_ag(
pag->pagl_leftrec != NULLAGINO &&
pag->pagl_rightrec != NULLAGINO) {
error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
- &trec, &doneleft, 1);
+ &trec, &doneleft);
if (error)
goto error1;
error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
- &rec, &doneright, 0);
+ &rec, &doneright);
if (error)
goto error1;
} else {
@@ -1074,6 +1069,177 @@ out_error:
return XFS_ERROR(error);
}
+/*
+ * Free disk inode. Carefully avoids touching the incore inode, all
+ * manipulations incore are the caller's responsibility.
+ * The on-disk inode is not changed by this operation, only the
+ * btree (free inode mask) is changed.
+ */
+int
+xfs_difree(
+ xfs_trans_t *tp, /* transaction pointer */
+ xfs_ino_t inode, /* inode to be freed */
+ xfs_bmap_free_t *flist, /* extents to free */
+ int *delete, /* set if inode cluster was deleted */
+ xfs_ino_t *first_ino) /* first inode in deleted cluster */
+{
+ /* REFERENCED */
+ xfs_agblock_t agbno; /* block number containing inode */
+ xfs_buf_t *agbp; /* buffer containing allocation group header */
+ xfs_agino_t agino; /* inode number relative to allocation group */
+ xfs_agnumber_t agno; /* allocation group number */
+ xfs_agi_t *agi; /* allocation group header */
+ xfs_btree_cur_t *cur; /* inode btree cursor */
+ int error; /* error return value */
+ int i; /* result code */
+ int ilen; /* inodes in an inode cluster */
+ xfs_mount_t *mp; /* mount structure for filesystem */
+ int off; /* offset of inode in inode chunk */
+ xfs_inobt_rec_incore_t rec; /* btree record */
+ struct xfs_perag *pag;
+
+ mp = tp->t_mountp;
+
+ /*
+ * Break up inode number into its components.
+ */
+ agno = XFS_INO_TO_AGNO(mp, inode);
+ if (agno >= mp->m_sb.sb_agcount) {
+ xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
+ __func__, agno, mp->m_sb.sb_agcount);
+ ASSERT(0);
+ return XFS_ERROR(EINVAL);
+ }
+ agino = XFS_INO_TO_AGINO(mp, inode);
+ if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
+ xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
+ __func__, (unsigned long long)inode,
+ (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
+ ASSERT(0);
+ return XFS_ERROR(EINVAL);
+ }
+ agbno = XFS_AGINO_TO_AGBNO(mp, agino);
+ if (agbno >= mp->m_sb.sb_agblocks) {
+ xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
+ __func__, agbno, mp->m_sb.sb_agblocks);
+ ASSERT(0);
+ return XFS_ERROR(EINVAL);
+ }
+ /*
+ * Get the allocation group header.
+ */
+ error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
+ if (error) {
+ xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
+ __func__, error);
+ return error;
+ }
+ agi = XFS_BUF_TO_AGI(agbp);
+ ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
+ ASSERT(agbno < be32_to_cpu(agi->agi_length));
+ /*
+ * Initialize the cursor.
+ */
+ cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
+
+ error = xfs_check_agi_freecount(cur, agi);
+ if (error)
+ goto error0;
+
+ /*
+ * Look for the entry describing this inode.
+ */
+ if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {
+ xfs_warn(mp, "%s: xfs_inobt_lookup() returned error %d.",
+ __func__, error);
+ goto error0;
+ }
+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+ error = xfs_inobt_get_rec(cur, &rec, &i);
+ if (error) {
+ xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.",
+ __func__, error);
+ goto error0;
+ }
+ XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+ /*
+ * Get the offset in the inode chunk.
+ */
+ off = agino - rec.ir_startino;
+ ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
+ ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off)));
+ /*
+ * Mark the inode free & increment the count.
+ */
+ rec.ir_free |= XFS_INOBT_MASK(off);
+ rec.ir_freecount++;
+
+ /*
+ * When an inode cluster is free, it becomes eligible for removal
+ */
+ if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
+ (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
+
+ *delete = 1;
+ *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
+
+ /*
+ * Remove the inode cluster from the AGI B+Tree, adjust the
+ * AGI and Superblock inode counts, and mark the disk space
+ * to be freed when the transaction is committed.
+ */
+ ilen = XFS_IALLOC_INODES(mp);
+ be32_add_cpu(&agi->agi_count, -ilen);
+ be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
+ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
+ pag = xfs_perag_get(mp, agno);
+ pag->pagi_freecount -= ilen - 1;
+ xfs_perag_put(pag);
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
+
+ if ((error = xfs_btree_delete(cur, &i))) {
+ xfs_warn(mp, "%s: xfs_btree_delete returned error %d.",
+ __func__, error);
+ goto error0;
+ }
+
+ xfs_bmap_add_free(XFS_AGB_TO_FSB(mp,
+ agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)),
+ XFS_IALLOC_BLOCKS(mp), flist, mp);
+ } else {
+ *delete = 0;
+
+ error = xfs_inobt_update(cur, &rec);
+ if (error) {
+ xfs_warn(mp, "%s: xfs_inobt_update returned error %d.",
+ __func__, error);
+ goto error0;
+ }
+
+ /*
+ * Change the inode free counts and log the ag/sb changes.
+ */
+ be32_add_cpu(&agi->agi_freecount, 1);
+ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
+ pag = xfs_perag_get(mp, agno);
+ pag->pagi_freecount++;
+ xfs_perag_put(pag);
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
+ }
+
+ error = xfs_check_agi_freecount(cur, agi);
+ if (error)
+ goto error0;
+
+ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+ return 0;
+
+error0:
+ xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
+ return error;
+}
+
STATIC int
xfs_imap_lookup(
struct xfs_mount *mp,
@@ -1153,7 +1319,7 @@ xfs_imap(
xfs_agblock_t cluster_agbno; /* first block in inode cluster */
int error; /* error code */
int offset; /* index of inode in its buffer */
- xfs_agblock_t offset_agbno; /* blks from chunk start to inode */
+ int offset_agbno; /* blks from chunk start to inode */
ASSERT(ino != NULLFSINO);
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 12/49] xfsprogs: define min/max once and use them everywhere.
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (10 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 18:42 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 13/49] libxfs: fix compile warnings Dave Chinner
` (37 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 1 -
include/platform_defs.h.in | 5 +++++
io/init.h | 3 ---
libxfs/rdwr.c | 1 -
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index bd74ca5..e776211 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -72,7 +72,6 @@
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))
-#define min(a,b) ((a) < (b) ? (a) : (b))
/*
* Argument structure for libxfs_init().
diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in
index 3c0106e..ac260bc 100644
--- a/include/platform_defs.h.in
+++ b/include/platform_defs.h.in
@@ -173,4 +173,9 @@ typedef unsigned short umode_t;
#define __arch_pack
#endif
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
#endif /* __XFS_PLATFORM_DEFS_H__ */
diff --git a/io/init.h b/io/init.h
index 1dac211..d773b1b 100644
--- a/io/init.h
+++ b/io/init.h
@@ -26,7 +26,4 @@ extern int expert;
extern size_t pagesize;
extern struct timeval stopwatch;
-#define min(a,b) (((a)<(b))?(a):(b))
-#define max(a,b) (((a)>(b))?(a):(b))
-
extern void init_cvtnum(size_t *blocksize, size_t *sectsize);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index c679f81..93beb23 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -22,7 +22,6 @@
#include "init.h"
#define BDSTRAT_SIZE (256 * 1024)
-#define min(x, y) ((x) < (y) ? (x) : (y))
#define IO_BCOMPARE_CHECK
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 13/49] libxfs: fix compile warnings
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (11 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 12/49] xfsprogs: define min/max once and use them everywhere Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 21:13 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write() Dave Chinner
` (36 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Some of the code shared with userspace causes compilation warnings
from things turned off in the kernel code, such as differences in
variable signedness. Fix those issues.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
copy/xfs_copy.c | 12 ++++++++++--
db/bmroot.c | 6 +++---
libxfs/xfs.h | 8 +++++++-
libxfs/xfs_attr_remote.c | 8 ++++----
libxfs/xfs_bmap.c | 3 ---
libxfs/xfs_da_btree.c | 6 +++---
libxfs/xfs_dir2_node.c | 2 ++
libxfs/xfs_ialloc.c | 2 +-
libxfs/xfs_rtalloc.c | 4 ++--
repair/attr_repair.c | 2 ++
repair/incore_ino.c | 2 ++
repair/scan.c | 1 +
12 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
index 39517da..bb37279 100644
--- a/copy/xfs_copy.c
+++ b/copy/xfs_copy.c
@@ -434,6 +434,10 @@ read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag,
off = XFS_AG_DADDR(mp, agno, XFS_SB_DADDR);
buf->position = (xfs_off_t) off * (xfs_off_t) BBSIZE;
length = buf->length = first_agbno * blocksize;
+ if (length == 0) {
+ do_log(_("ag header buffer invalid!\n"));
+ exit(1);
+ }
/* handle alignment stuff */
@@ -449,7 +453,6 @@ read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag,
if (buf->length % buf->min_io_size != 0)
buf->length = roundup(buf->length, buf->min_io_size);
- ASSERT(length != 0);
read_wbuf(fd, buf, mp);
ASSERT(buf->length >= length);
@@ -936,7 +939,12 @@ main(int argc, char **argv)
for (;;) {
/* none of this touches the w_buf buffer */
- ASSERT(current_level < btree_levels);
+ if (current_level >= btree_levels) {
+ do_log(
+ _("Error: current level %d >= btree levels %d\n"),
+ current_level, btree_levels);
+ exit(1);
+ }
current_level++;
diff --git a/db/bmroot.c b/db/bmroot.c
index 3e18917..12b129e 100644
--- a/db/bmroot.c
+++ b/db/bmroot.c
@@ -91,13 +91,13 @@ bmroota_key_offset(
int idx)
{
xfs_bmdr_block_t *block;
- /* REFERENCED */
- xfs_dinode_t *dip;
+#ifdef DEBUG
+ xfs_dinode_t *dip = obj;
+#endif
xfs_bmdr_key_t *kp;
ASSERT(bitoffs(startoff) == 0);
ASSERT(obj == iocur_top->data);
- dip = obj;
block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip));
ASSERT(be16_to_cpu(block->bb_level) > 0);
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 3fd226c..c9d6a6d 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -189,7 +189,9 @@ roundup_pow_of_two(uint v)
/* avoid gcc warning */
#define xfs_incore(bt,blkno,len,lockit) ({ \
typeof(blkno) __foo = (blkno); \
+ typeof(len) __bar = (len); \
(blkno) = __foo; \
+ (len) = __bar; /* no set-but-unused warning */ \
NULL; \
})
#define xfs_buf_relse(bp) libxfs_putbuf(bp)
@@ -259,7 +261,11 @@ roundup_pow_of_two(uint v)
#define xfs_trans_agblocks_delta(tp, d)
#define xfs_trans_agflist_delta(tp, d)
#define xfs_trans_agbtree_delta(tp, d)
-#define xfs_trans_buf_set_type(tp, bp, t)
+#define xfs_trans_buf_set_type(tp, bp, t) ({ \
+ int __t = (t); \
+ __t = __t; /* no set-but-unused warning */ \
+})
+
#define xfs_trans_buf_copy_type(dbp, sbp)
#define xfs_buf_readahead(a,b,c,ops) ((void) 0) /* no readahead */
diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c
index 0b2ca8c..59bb12d 100644
--- a/libxfs/xfs_attr_remote.c
+++ b/libxfs/xfs_attr_remote.c
@@ -214,7 +214,7 @@ xfs_attr_rmtval_copyout(
xfs_ino_t ino,
int *offset,
int *valuelen,
- char **dst)
+ __uint8_t **dst)
{
char *src = bp->b_addr;
xfs_daddr_t bno = bp->b_bn;
@@ -261,7 +261,7 @@ xfs_attr_rmtval_copyin(
xfs_ino_t ino,
int *offset,
int *valuelen,
- char **src)
+ __uint8_t **src)
{
char *dst = bp->b_addr;
xfs_daddr_t bno = bp->b_bn;
@@ -314,7 +314,7 @@ xfs_attr_rmtval_get(
struct xfs_mount *mp = args->dp->i_mount;
struct xfs_buf *bp;
xfs_dablk_t lblkno = args->rmtblkno;
- char *dst = args->value;
+ __uint8_t *dst = args->value;
int valuelen = args->valuelen;
int nmap;
int error;
@@ -378,7 +378,7 @@ xfs_attr_rmtval_set(
struct xfs_bmbt_irec map;
xfs_dablk_t lblkno;
xfs_fileoff_t lfileoff = 0;
- char *src = args->value;
+ __uint8_t *src = args->value;
int blkcnt;
int valuelen;
int nmap;
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 6664265..b7f798b 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -4437,12 +4437,9 @@ xfs_bmapi_allocate(
struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
int tmp_logflags = 0;
int error;
- int rt;
ASSERT(bma->length > 0);
- rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip);
-
/*
* For the wasdelay case, we could also just allocate the stuff asked
* for in this bmap call but that wouldn't be as good.
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index d7798af..b7b6705 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -376,7 +376,7 @@ xfs_da3_split(
struct xfs_da_intnode *node;
struct xfs_buf *bp;
int max;
- int action;
+ int action = 0;
int error;
int i;
@@ -2431,9 +2431,9 @@ static int
xfs_buf_map_from_irec(
struct xfs_mount *mp,
struct xfs_buf_map **mapp,
- unsigned int *nmaps,
+ int *nmaps,
struct xfs_bmbt_irec *irecs,
- unsigned int nirecs)
+ int nirecs)
{
struct xfs_buf_map *map;
int i;
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index 222f08c..d2bd249 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -295,11 +295,13 @@ xfs_dir2_free_log_header(
struct xfs_trans *tp,
struct xfs_buf *bp)
{
+#ifdef DEBUG
xfs_dir2_free_t *free; /* freespace structure */
free = bp->b_addr;
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
+#endif
xfs_trans_log_buf(tp, bp, 0, xfs_dir3_free_hdr_size(tp->t_mountp) - 1);
}
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 98513fd..4683287 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -1319,7 +1319,7 @@ xfs_imap(
xfs_agblock_t cluster_agbno; /* first block in inode cluster */
int error; /* error code */
int offset; /* index of inode in its buffer */
- int offset_agbno; /* blks from chunk start to inode */
+ xfs_agblock_t offset_agbno; /* blks from chunk start to inode */
ASSERT(ino != NULLFSINO);
diff --git a/libxfs/xfs_rtalloc.c b/libxfs/xfs_rtalloc.c
index 1de85fd..9797db7 100644
--- a/libxfs/xfs_rtalloc.c
+++ b/libxfs/xfs_rtalloc.c
@@ -431,8 +431,8 @@ xfs_rtfree_range(
{
xfs_rtblock_t end; /* end of the freed extent */
int error; /* error value */
- xfs_rtblock_t postblock; /* first block freed > end */
- xfs_rtblock_t preblock; /* first block freed < start */
+ xfs_rtblock_t postblock = 0; /* first block freed > end */
+ xfs_rtblock_t preblock = 0; /* first block freed < start */
end = start + len - 1;
/*
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index d42b85f..ba85fd9 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -1631,9 +1631,11 @@ process_attributes(
{
int err;
__u8 aformat = dip->di_aformat;
+#ifdef DEBUG
xfs_attr_shortform_t *asf;
asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip);
+#endif
if (aformat == XFS_DINODE_FMT_LOCAL) {
ASSERT(be16_to_cpu(asf->hdr.totsize) <=
diff --git a/repair/incore_ino.c b/repair/incore_ino.c
index 2a40727..158cf3a 100644
--- a/repair/incore_ino.c
+++ b/repair/incore_ino.c
@@ -167,6 +167,7 @@ __uint32_t num_inode_references(struct ino_tree_node *irec, int ino_offset)
default:
ASSERT(0);
}
+ return 0;
}
void set_inode_disk_nlinks(struct ino_tree_node *irec, int ino_offset,
@@ -207,6 +208,7 @@ __uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int ino_offset)
default:
ASSERT(0);
}
+ return 0;
}
/*
diff --git a/repair/scan.c b/repair/scan.c
index d58d55a..e76ce47 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -520,6 +520,7 @@ scan_allocbt(
name = "cnt";
break;
default:
+ name = "(unknown)";
assert(0);
break;
}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write()
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (12 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 13/49] libxfs: fix compile warnings Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 21:42 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 15/49] libxfs: local to remote format support of remote symlinks Dave Chinner
` (35 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The conversion from local format to extent format requires
interpretation of the data in the fork being converted, so it cannot
be done in a generic way. It is up to the caller to convert the fork
format to extent format before calling into xfs_bmapi_write() so
format conversion can be done correctly.
The code in xfs_bmapi_write() to convert the format is used
implicitly by the attribute and directory code, but they
specifically zero the fork size so that the conversion does not do
any allocation or manipulation. Move this conversion into the
shortform to leaf functions for the dir/attr code so the conversions
are explicitly controlled by all callers.
Now we can remove the conversion code in xfs_bmapi_write.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_bmap.h | 1 +
libxfs/xfs_attr_leaf.c | 2 +
libxfs/xfs_bmap.c | 197 ++++++++++++++++++++----------------------------
libxfs/xfs_dir2_block.c | 19 +++--
4 files changed, 97 insertions(+), 122 deletions(-)
diff --git a/include/xfs_bmap.h b/include/xfs_bmap.h
index de451a2..ffa67b1 100644
--- a/include/xfs_bmap.h
+++ b/include/xfs_bmap.h
@@ -169,6 +169,7 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,
#endif
int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
+void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len,
struct xfs_bmap_free *flist, struct xfs_mount *mp);
void xfs_bmap_cancel(struct xfs_bmap_free *flist);
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 49a1764..c09b0f3 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -654,6 +654,8 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
sf = (xfs_attr_shortform_t *)tmpbuffer;
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
+ xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK);
+
bp = NULL;
error = xfs_da_grow_inode(args, &blkno);
if (error) {
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index b7f798b..5234674 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -1042,6 +1042,24 @@ xfs_bmap_extents_to_btree(
* since the file data needs to get logged so things will stay consistent.
* (The bmap-level manipulations are ok, though).
*/
+void
+xfs_bmap_local_to_extents_empty(
+ struct xfs_inode *ip,
+ int whichfork)
+{
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
+
+ ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
+ ASSERT(ifp->if_bytes == 0);
+ ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
+
+ xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
+ ifp->if_flags &= ~XFS_IFINLINE;
+ ifp->if_flags |= XFS_IFEXTENTS;
+ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
+}
+
+
STATIC int /* error */
xfs_bmap_local_to_extents(
xfs_trans_t *tp, /* transaction pointer */
@@ -1055,9 +1073,12 @@ xfs_bmap_local_to_extents(
struct xfs_inode *ip,
struct xfs_ifork *ifp))
{
- int error; /* error return value */
+ int error = 0;
int flags; /* logging flags returned */
xfs_ifork_t *ifp; /* inode fork pointer */
+ xfs_alloc_arg_t args; /* allocation arguments */
+ xfs_buf_t *bp; /* buffer for extent block */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
/*
* We don't want to deal with the case of keeping inode data inline yet.
@@ -1066,68 +1087,65 @@ xfs_bmap_local_to_extents(
ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK));
ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
+
+ if (!ifp->if_bytes) {
+ xfs_bmap_local_to_extents_empty(ip, whichfork);
+ flags = XFS_ILOG_CORE;
+ goto done;
+ }
+
flags = 0;
error = 0;
- if (ifp->if_bytes) {
- xfs_alloc_arg_t args; /* allocation arguments */
- xfs_buf_t *bp; /* buffer for extent block */
- xfs_bmbt_rec_host_t *ep;/* extent record pointer */
-
- ASSERT((ifp->if_flags &
- (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
- memset(&args, 0, sizeof(args));
- args.tp = tp;
- args.mp = ip->i_mount;
- args.firstblock = *firstblock;
- /*
- * Allocate a block. We know we need only one, since the
- * file currently fits in an inode.
- */
- if (*firstblock == NULLFSBLOCK) {
- args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
- args.type = XFS_ALLOCTYPE_START_BNO;
- } else {
- args.fsbno = *firstblock;
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- }
- args.total = total;
- args.minlen = args.maxlen = args.prod = 1;
- error = xfs_alloc_vextent(&args);
- if (error)
- goto done;
-
- /* Can't fail, the space was reserved. */
- ASSERT(args.fsbno != NULLFSBLOCK);
- ASSERT(args.len == 1);
- *firstblock = args.fsbno;
- bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
-
- /* initialise the block and copy the data */
- init_fn(tp, bp, ip, ifp);
-
- /* account for the change in fork size and log everything */
- xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
- xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
- xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
- xfs_iext_add(ifp, 0, 1);
- ep = xfs_iext_get_ext(ifp, 0);
- xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
- trace_xfs_bmap_post_update(ip, 0,
- whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
- _THIS_IP_);
- XFS_IFORK_NEXT_SET(ip, whichfork, 1);
- ip->i_d.di_nblocks = 1;
- xfs_trans_mod_dquot_byino(tp, ip,
- XFS_TRANS_DQ_BCOUNT, 1L);
- flags |= xfs_ilog_fext(whichfork);
+ ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) ==
+ XFS_IFINLINE);
+ memset(&args, 0, sizeof(args));
+ args.tp = tp;
+ args.mp = ip->i_mount;
+ args.firstblock = *firstblock;
+ /*
+ * Allocate a block. We know we need only one, since the
+ * file currently fits in an inode.
+ */
+ if (*firstblock == NULLFSBLOCK) {
+ args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
+ args.type = XFS_ALLOCTYPE_START_BNO;
} else {
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
- xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
+ args.fsbno = *firstblock;
+ args.type = XFS_ALLOCTYPE_NEAR_BNO;
}
- ifp->if_flags &= ~XFS_IFINLINE;
- ifp->if_flags |= XFS_IFEXTENTS;
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
+ args.total = total;
+ args.minlen = args.maxlen = args.prod = 1;
+ error = xfs_alloc_vextent(&args);
+ if (error)
+ goto done;
+
+ /* Can't fail, the space was reserved. */
+ ASSERT(args.fsbno != NULLFSBLOCK);
+ ASSERT(args.len == 1);
+ *firstblock = args.fsbno;
+ bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
+
+ /* initialise the block and copy the data */
+ init_fn(tp, bp, ip, ifp);
+
+ /* account for the change in fork size and log everything */
+ xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
+ xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
+ xfs_bmap_local_to_extents_empty(ip, whichfork);
flags |= XFS_ILOG_CORE;
+
+ xfs_iext_add(ifp, 0, 1);
+ ep = xfs_iext_get_ext(ifp, 0);
+ xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
+ trace_xfs_bmap_post_update(ip, 0,
+ whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
+ _THIS_IP_);
+ XFS_IFORK_NEXT_SET(ip, whichfork, 1);
+ ip->i_d.di_nblocks = 1;
+ xfs_trans_mod_dquot_byino(tp, ip,
+ XFS_TRANS_DQ_BCOUNT, 1L);
+ flags |= xfs_ilog_fext(whichfork);
+
done:
*logflagsp = flags;
return error;
@@ -1203,23 +1221,6 @@ xfs_bmap_add_attrfork_extents(
return error;
}
-/*
- * Block initialisation functions for local to extent format conversion.
- * As these get more complex, they will be moved to the relevant files,
- * but for now they are too simple to worry about.
- */
-STATIC void
-xfs_bmap_local_to_extents_init_fn(
- struct xfs_trans *tp,
- struct xfs_buf *bp,
- struct xfs_inode *ip,
- struct xfs_ifork *ifp)
-{
- bp->b_ops = &xfs_bmbt_buf_ops;
- memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
- xfs_trans_buf_set_type(tp, bp, XFS_BLFT_BTREE_BUF);
-}
-
STATIC void
xfs_symlink_local_to_remote(
struct xfs_trans *tp,
@@ -1272,9 +1273,9 @@ xfs_bmap_add_attrfork_local(
flags, XFS_DATA_FORK,
xfs_symlink_local_to_remote);
- return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
- XFS_DATA_FORK,
- xfs_bmap_local_to_extents_init_fn);
+ /* should only be called for types that support local format data */
+ ASSERT(0);
+ return EFSCORRUPTED;
}
/*
@@ -4653,20 +4654,19 @@ xfs_bmapi_write(
orig_mval = mval;
orig_nmap = *nmap;
#endif
+ whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
+ XFS_ATTR_FORK : XFS_DATA_FORK;
ASSERT(*nmap >= 1);
ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
ASSERT(!(flags & XFS_BMAPI_IGSTATE));
ASSERT(tp != NULL);
ASSERT(len > 0);
-
- whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
- XFS_ATTR_FORK : XFS_DATA_FORK;
+ ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
if (unlikely(XFS_TEST_ERROR(
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
+ XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
@@ -4679,37 +4679,6 @@ xfs_bmapi_write(
XFS_STATS_INC(xs_blk_mapw);
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- /*
- * XXX (dgc): This assumes we are only called for inodes that
- * contain content neutral data in local format. Anything that
- * contains caller-specific data in local format that needs
- * transformation to move to a block format needs to do the
- * conversion to extent format itself.
- *
- * Directory data forks and attribute forks handle this
- * themselves, but with the addition of metadata verifiers every
- * data fork in local format now contains caller specific data
- * and as such conversion through this function is likely to be
- * broken.
- *
- * The only likely user of this branch is for remote symlinks,
- * but we cannot overwrite the data fork contents of the symlink
- * (EEXIST occurs higher up the stack) and so it will never go
- * from local format to extent format here. Hence I don't think
- * this branch is ever executed intentionally and we should
- * consider removing it and asserting that xfs_bmapi_write()
- * cannot be called directly on local format forks. i.e. callers
- * are completely responsible for local to extent format
- * conversion, not xfs_bmapi_write().
- */
- error = xfs_bmap_local_to_extents(tp, ip, firstblock, total,
- &bma.logflags, whichfork,
- xfs_bmap_local_to_extents_init_fn);
- if (error)
- goto error0;
- }
-
if (*firstblock == NULLFSBLOCK) {
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index dc69394..d94b9b2 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -1051,13 +1051,15 @@ xfs_dir2_sf_to_block(
__be16 *tagp; /* end of data entry */
xfs_trans_t *tp; /* transaction pointer */
struct xfs_name name;
+ struct xfs_ifork *ifp;
trace_xfs_dir2_sf_to_block(args);
dp = args->dp;
tp = args->trans;
mp = dp->i_mount;
- ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
+ ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
+ ASSERT(ifp->if_flags & XFS_IFINLINE);
/*
* Bomb out if the shortform directory is way too short.
*/
@@ -1066,22 +1068,23 @@ xfs_dir2_sf_to_block(
return XFS_ERROR(EIO);
}
- oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
+ oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data;
- ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
- ASSERT(dp->i_df.if_u1.if_data != NULL);
+ ASSERT(ifp->if_bytes == dp->i_d.di_size);
+ ASSERT(ifp->if_u1.if_data != NULL);
ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count));
+ ASSERT(dp->i_d.di_nextents == 0);
/*
* Copy the directory into a temporary buffer.
* Then pitch the incore inode data so we can make extents.
*/
- sfp = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP);
- memcpy(sfp, oldsfp, dp->i_df.if_bytes);
+ sfp = kmem_alloc(ifp->if_bytes, KM_SLEEP);
+ memcpy(sfp, oldsfp, ifp->if_bytes);
- xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK);
+ xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK);
+ xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK);
dp->i_d.di_size = 0;
- xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
/*
* Add block 0 to the inode.
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 15/49] libxfs: local to remote format support of remote symlinks
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (13 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write() Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-02 22:22 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 16/49] xfs: separate out log format definitions Dave Chinner
` (34 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
This conversion was overlooked earlier on. Now that the differences
between userspace and kernel space are getting smaller this bug is
obvious. Fix it.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_symlink.h | 2 ++
libxfs/xfs_bmap.c | 12 ------------
libxfs/xfs_symlink.c | 29 +++++++++++++++++++++++++++++
3 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/include/xfs_symlink.h b/include/xfs_symlink.h
index 55f3f2d..e85dfd1 100644
--- a/include/xfs_symlink.h
+++ b/include/xfs_symlink.h
@@ -31,6 +31,8 @@ struct xfs_dsymlink_hdr {
int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
uint32_t size, struct xfs_buf *bp);
+void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
+ struct xfs_inode *ip, struct xfs_ifork *ifp);
extern const struct xfs_buf_ops xfs_symlink_buf_ops;
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 5234674..ce72b87 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -1221,18 +1221,6 @@ xfs_bmap_add_attrfork_extents(
return error;
}
-STATIC void
-xfs_symlink_local_to_remote(
- struct xfs_trans *tp,
- struct xfs_buf *bp,
- struct xfs_inode *ip,
- struct xfs_ifork *ifp)
-{
- /* remote symlink blocks are not verifiable until CRCs come along */
- bp->b_ops = NULL;
- memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
-}
-
/*
* Called from xfs_bmap_add_attrfork to handle local format files. Each
* different data fork content type needs a different callout to do the
diff --git a/libxfs/xfs_symlink.c b/libxfs/xfs_symlink.c
index 860b123..f2e69f9 100644
--- a/libxfs/xfs_symlink.c
+++ b/libxfs/xfs_symlink.c
@@ -145,3 +145,32 @@ const struct xfs_buf_ops xfs_symlink_buf_ops = {
.verify_write = xfs_symlink_write_verify,
};
+void
+xfs_symlink_local_to_remote(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp,
+ struct xfs_inode *ip,
+ struct xfs_ifork *ifp)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ char *buf;
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+ bp->b_ops = NULL;
+ memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
+ return;
+ }
+
+ /*
+ * As this symlink fits in an inode literal area, it must also fit in
+ * the smallest buffer the filesystem supports.
+ */
+ ASSERT(BBTOB(bp->b_length) >=
+ ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr));
+
+ bp->b_ops = &xfs_symlink_buf_ops;
+
+ buf = bp->b_addr;
+ buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp);
+ memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes);
+}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 16/49] xfs: separate out log format definitions
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (14 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 15/49] libxfs: local to remote format support of remote symlinks Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-03 15:15 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 17/49] xfs: split out inode log item format definition Dave Chinner
` (33 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The on-disk format definitions for the log are spread randoms
through a couple of header files. Consolidate it all in a single
file that can be shared easily with userspace. This means that
xfs_log.h and xfs_log_priv.h no longer need to be shared with
userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 4 +-
include/libxfs.h | 4 +-
include/libxlog.h | 6 -
include/xfs_log.h | 190 -------------
include/xfs_log_format.h | 178 ++++++++++++
include/xfs_log_priv.h | 692 ----------------------------------------------
libxfs/rdwr.c | 2 -
libxlog/xfs_log_recover.c | 3 +
8 files changed, 186 insertions(+), 893 deletions(-)
delete mode 100644 include/xfs_log.h
create mode 100644 include/xfs_log_format.h
delete mode 100644 include/xfs_log_priv.h
diff --git a/include/Makefile b/include/Makefile
index ba2c80d..efa3275 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -27,7 +27,9 @@ QAHFILES = libxfs.h libxlog.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \
xfs_icreate_item.h xfs_inode.h xfs_inode_item.h xfs_inum.h \
- xfs_log.h xfs_log_priv.h xfs_log_recover.h xfs_metadump.h \
+ xfs_log_format.h \
+ xfs_log_recover.h \
+ xfs_metadump.h \
xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h xfs_symlink.h \
xfs_trace.h xfs_trans.h xfs_trans_space.h xfs_dfrag.h
diff --git a/include/libxfs.h b/include/libxfs.h
index e776211..c9918cd 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -59,6 +59,8 @@
#include <xfs/xfs_symlink.h>
#include <xfs/xfs_icreate_item.h>
+#include <xfs/xfs_log_format.h>
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
@@ -613,8 +615,6 @@ extern unsigned long libxfs_physmem(void); /* in kilobytes */
#include <xfs/xfs_attr_remote.h>
#include <xfs/xfs_quota.h>
#include <xfs/xfs_trans_space.h>
-#include <xfs/xfs_log.h>
-#include <xfs/xfs_log_priv.h>
#define XFS_INOBT_IS_FREE_DISK(rp,i) \
((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0)
diff --git a/include/libxlog.h b/include/libxlog.h
index ff711e9..961c4b5 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -53,12 +53,6 @@ struct xlog {
#include <xfs/xfs_extfree_item.h>
#include <xfs/xfs_icreate_item.h>
-typedef union {
- xlog_rec_header_t hic_header;
- xlog_rec_ext_header_t hic_xheader;
- char hic_sector[XLOG_HEADER_SIZE];
-} xlog_in_core_2_t;
-
/*
* macros mapping kernel code to user code
*/
diff --git a/include/xfs_log.h b/include/xfs_log.h
deleted file mode 100644
index 70cc014..0000000
--- a/include/xfs_log.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_LOG_H__
-#define __XFS_LOG_H__
-
-/* get lsn fields */
-#define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
-#define BLOCK_LSN(lsn) ((uint)(lsn))
-
-/* this is used in a spot where we might otherwise double-endian-flip */
-#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
-
-#ifdef __KERNEL__
-/*
- * By comparing each component, we don't have to worry about extra
- * endian issues in treating two 32 bit numbers as one 64 bit number
- */
-static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
-{
- if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
- return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
-
- if (BLOCK_LSN(lsn1) != BLOCK_LSN(lsn2))
- return (BLOCK_LSN(lsn1)<BLOCK_LSN(lsn2))? -999 : 999;
-
- return 0;
-}
-
-#define XFS_LSN_CMP(x,y) _lsn_cmp(x,y)
-
-/*
- * Macros, structures, prototypes for interface to the log manager.
- */
-
-/*
- * Flags to xfs_log_done()
- */
-#define XFS_LOG_REL_PERM_RESERV 0x1
-
-/*
- * Flags to xfs_log_force()
- *
- * XFS_LOG_SYNC: Synchronous force in-core log to disk
- */
-#define XFS_LOG_SYNC 0x1
-
-#endif /* __KERNEL__ */
-
-
-/* Log Clients */
-#define XFS_TRANSACTION 0x69
-#define XFS_VOLUME 0x2
-#define XFS_LOG 0xaa
-
-
-/* Region types for iovec's i_type */
-#define XLOG_REG_TYPE_BFORMAT 1
-#define XLOG_REG_TYPE_BCHUNK 2
-#define XLOG_REG_TYPE_EFI_FORMAT 3
-#define XLOG_REG_TYPE_EFD_FORMAT 4
-#define XLOG_REG_TYPE_IFORMAT 5
-#define XLOG_REG_TYPE_ICORE 6
-#define XLOG_REG_TYPE_IEXT 7
-#define XLOG_REG_TYPE_IBROOT 8
-#define XLOG_REG_TYPE_ILOCAL 9
-#define XLOG_REG_TYPE_IATTR_EXT 10
-#define XLOG_REG_TYPE_IATTR_BROOT 11
-#define XLOG_REG_TYPE_IATTR_LOCAL 12
-#define XLOG_REG_TYPE_QFORMAT 13
-#define XLOG_REG_TYPE_DQUOT 14
-#define XLOG_REG_TYPE_QUOTAOFF 15
-#define XLOG_REG_TYPE_LRHEADER 16
-#define XLOG_REG_TYPE_UNMOUNT 17
-#define XLOG_REG_TYPE_COMMIT 18
-#define XLOG_REG_TYPE_TRANSHDR 19
-#define XLOG_REG_TYPE_ICREATE 20
-#define XLOG_REG_TYPE_MAX 20
-
-typedef struct xfs_log_iovec {
- void *i_addr; /* beginning address of region */
- int i_len; /* length in bytes of region */
- uint i_type; /* type of region */
-} xfs_log_iovec_t;
-
-struct xfs_log_vec {
- struct xfs_log_vec *lv_next; /* next lv in build list */
- int lv_niovecs; /* number of iovecs in lv */
- struct xfs_log_iovec *lv_iovecp; /* iovec array */
- struct xfs_log_item *lv_item; /* owner */
- char *lv_buf; /* formatted buffer */
- int lv_buf_len; /* size of formatted buffer */
-};
-
-/*
- * Structure used to pass callback function and the function's argument
- * to the log manager.
- */
-typedef struct xfs_log_callback {
- struct xfs_log_callback *cb_next;
- void (*cb_func)(void *, int);
- void *cb_arg;
-} xfs_log_callback_t;
-
-
-#ifdef __KERNEL__
-/* Log manager interfaces */
-struct xfs_mount;
-struct xlog_in_core;
-struct xlog_ticket;
-struct xfs_log_item;
-struct xfs_item_ops;
-struct xfs_trans;
-
-void xfs_log_item_init(struct xfs_mount *mp,
- struct xfs_log_item *item,
- int type,
- const struct xfs_item_ops *ops);
-
-xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
- struct xlog_ticket *ticket,
- struct xlog_in_core **iclog,
- uint flags);
-int _xfs_log_force(struct xfs_mount *mp,
- uint flags,
- int *log_forced);
-void xfs_log_force(struct xfs_mount *mp,
- uint flags);
-int _xfs_log_force_lsn(struct xfs_mount *mp,
- xfs_lsn_t lsn,
- uint flags,
- int *log_forced);
-void xfs_log_force_lsn(struct xfs_mount *mp,
- xfs_lsn_t lsn,
- uint flags);
-int xfs_log_mount(struct xfs_mount *mp,
- struct xfs_buftarg *log_target,
- xfs_daddr_t start_block,
- int num_bblocks);
-int xfs_log_mount_finish(struct xfs_mount *mp);
-xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
-xfs_lsn_t xlog_assign_tail_lsn_locked(struct xfs_mount *mp);
-void xfs_log_space_wake(struct xfs_mount *mp);
-int xfs_log_notify(struct xfs_mount *mp,
- struct xlog_in_core *iclog,
- xfs_log_callback_t *callback_entry);
-int xfs_log_release_iclog(struct xfs_mount *mp,
- struct xlog_in_core *iclog);
-int xfs_log_reserve(struct xfs_mount *mp,
- int length,
- int count,
- struct xlog_ticket **ticket,
- __uint8_t clientid,
- bool permanent,
- uint t_type);
-int xfs_log_regrant(struct xfs_mount *mp, struct xlog_ticket *tic);
-int xfs_log_unmount_write(struct xfs_mount *mp);
-void xfs_log_unmount(struct xfs_mount *mp);
-int xfs_log_force_umount(struct xfs_mount *mp, int logerror);
-int xfs_log_need_covered(struct xfs_mount *mp);
-
-void xlog_iodone(struct xfs_buf *);
-
-struct xlog_ticket *xfs_log_ticket_get(struct xlog_ticket *ticket);
-void xfs_log_ticket_put(struct xlog_ticket *ticket);
-
-int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
- xfs_lsn_t *commit_lsn, int flags);
-bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
-
-void xfs_log_work_queue(struct xfs_mount *mp);
-void xfs_log_worker(struct work_struct *work);
-void xfs_log_quiesce(struct xfs_mount *mp);
-
-#endif
-#endif /* __XFS_LOG_H__ */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
new file mode 100644
index 0000000..9f9aeb6
--- /dev/null
+++ b/include/xfs_log_format.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_LOG_FORMAT_H__
+#define __XFS_LOG_FORMAT_H__
+
+typedef __uint32_t xlog_tid_t;
+
+#define XLOG_MIN_ICLOGS 2
+#define XLOG_MAX_ICLOGS 8
+#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
+#define XLOG_VERSION_1 1
+#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
+#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
+#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */
+#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
+#define XLOG_MAX_RECORD_BSIZE (256*1024)
+#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
+#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
+#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
+#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
+#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
+ (log)->l_mp->m_sb.sb_logsunit)
+#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit)
+
+#define XLOG_HEADER_SIZE 512
+
+#define XLOG_REC_SHIFT(log) \
+ BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
+ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
+#define XLOG_TOTAL_REC_SHIFT(log) \
+ BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
+ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
+
+/* get lsn fields */
+#define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
+#define BLOCK_LSN(lsn) ((uint)(lsn))
+
+/* this is used in a spot where we might otherwise double-endian-flip */
+#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
+
+static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
+{
+ return ((xfs_lsn_t)cycle << 32) | block;
+}
+
+static inline uint xlog_get_cycle(char *ptr)
+{
+ if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
+ return be32_to_cpu(*((__be32 *)ptr + 1));
+ else
+ return be32_to_cpu(*(__be32 *)ptr);
+}
+
+/* Log Clients */
+#define XFS_TRANSACTION 0x69
+#define XFS_VOLUME 0x2
+#define XFS_LOG 0xaa
+
+#define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */
+
+/* Region types for iovec's i_type */
+#define XLOG_REG_TYPE_BFORMAT 1
+#define XLOG_REG_TYPE_BCHUNK 2
+#define XLOG_REG_TYPE_EFI_FORMAT 3
+#define XLOG_REG_TYPE_EFD_FORMAT 4
+#define XLOG_REG_TYPE_IFORMAT 5
+#define XLOG_REG_TYPE_ICORE 6
+#define XLOG_REG_TYPE_IEXT 7
+#define XLOG_REG_TYPE_IBROOT 8
+#define XLOG_REG_TYPE_ILOCAL 9
+#define XLOG_REG_TYPE_IATTR_EXT 10
+#define XLOG_REG_TYPE_IATTR_BROOT 11
+#define XLOG_REG_TYPE_IATTR_LOCAL 12
+#define XLOG_REG_TYPE_QFORMAT 13
+#define XLOG_REG_TYPE_DQUOT 14
+#define XLOG_REG_TYPE_QUOTAOFF 15
+#define XLOG_REG_TYPE_LRHEADER 16
+#define XLOG_REG_TYPE_UNMOUNT 17
+#define XLOG_REG_TYPE_COMMIT 18
+#define XLOG_REG_TYPE_TRANSHDR 19
+#define XLOG_REG_TYPE_ICREATE 20
+#define XLOG_REG_TYPE_MAX 20
+
+/*
+ * Flags to log operation header
+ *
+ * The first write of a new transaction will be preceded with a start
+ * record, XLOG_START_TRANS. Once a transaction is committed, a commit
+ * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into
+ * the remainder of the current active in-core log, it is split up into
+ * multiple regions. Each partial region will be marked with a
+ * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS.
+ *
+ */
+#define XLOG_START_TRANS 0x01 /* Start a new transaction */
+#define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */
+#define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */
+#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */
+#define XLOG_END_TRANS 0x10 /* End a continued transaction */
+#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */
+
+
+typedef struct xlog_op_header {
+ __be32 oh_tid; /* transaction id of operation : 4 b */
+ __be32 oh_len; /* bytes in data region : 4 b */
+ __u8 oh_clientid; /* who sent me this : 1 b */
+ __u8 oh_flags; /* : 1 b */
+ __u16 oh_res2; /* 32 bit align : 2 b */
+} xlog_op_header_t;
+
+
+/* valid values for h_fmt */
+#define XLOG_FMT_UNKNOWN 0
+#define XLOG_FMT_LINUX_LE 1
+#define XLOG_FMT_LINUX_BE 2
+#define XLOG_FMT_IRIX_BE 3
+
+/* our fmt */
+#ifdef XFS_NATIVE_HOST
+#define XLOG_FMT XLOG_FMT_LINUX_BE
+#else
+#define XLOG_FMT XLOG_FMT_LINUX_LE
+#endif
+
+typedef struct xlog_rec_header {
+ __be32 h_magicno; /* log record (LR) identifier : 4 */
+ __be32 h_cycle; /* write cycle of log : 4 */
+ __be32 h_version; /* LR version : 4 */
+ __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */
+ __be64 h_lsn; /* lsn of this LR : 8 */
+ __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
+ __le32 h_crc; /* crc of log record : 4 */
+ __be32 h_prev_block; /* block number to previous LR : 4 */
+ __be32 h_num_logops; /* number of log operations in this LR : 4 */
+ __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
+ /* new fields */
+ __be32 h_fmt; /* format of log record : 4 */
+ uuid_t h_fs_uuid; /* uuid of FS : 16 */
+ __be32 h_size; /* iclog size : 4 */
+} xlog_rec_header_t;
+
+typedef struct xlog_rec_ext_header {
+ __be32 xh_cycle; /* write cycle of log : 4 */
+ __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
+} xlog_rec_ext_header_t;
+
+/*
+ * Quite misnamed, because this union lays out the actual on-disk log buffer.
+ */
+typedef union xlog_in_core2 {
+ xlog_rec_header_t hic_header;
+ xlog_rec_ext_header_t hic_xheader;
+ char hic_sector[XLOG_HEADER_SIZE];
+} xlog_in_core_2_t;
+
+/* not an on-disk structure, but needed by log recovery in userspace */
+typedef struct xfs_log_iovec {
+ void *i_addr; /* beginning address of region */
+ int i_len; /* length in bytes of region */
+ uint i_type; /* type of region */
+} xfs_log_iovec_t;
+
+#endif /* __XFS_LOG_FORMAT_H__ */
diff --git a/include/xfs_log_priv.h b/include/xfs_log_priv.h
deleted file mode 100644
index 16d8d12..0000000
--- a/include/xfs_log_priv.h
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_LOG_PRIV_H__
-#define __XFS_LOG_PRIV_H__
-
-struct xfs_buf;
-struct xlog;
-struct xlog_ticket;
-struct xfs_mount;
-
-/*
- * Macros, structures, prototypes for internal log manager use.
- */
-
-#define XLOG_MIN_ICLOGS 2
-#define XLOG_MAX_ICLOGS 8
-#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
-#define XLOG_VERSION_1 1
-#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
-#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
-#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */
-#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
-#define XLOG_MAX_RECORD_BSIZE (256*1024)
-#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
-#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
-#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
-#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
-#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
- (log)->l_mp->m_sb.sb_logsunit)
-#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit)
-
-#define XLOG_HEADER_SIZE 512
-
-#define XLOG_REC_SHIFT(log) \
- BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
- XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
-#define XLOG_TOTAL_REC_SHIFT(log) \
- BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
- XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
-
-static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
-{
- return ((xfs_lsn_t)cycle << 32) | block;
-}
-
-static inline uint xlog_get_cycle(char *ptr)
-{
- if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
- return be32_to_cpu(*((__be32 *)ptr + 1));
- else
- return be32_to_cpu(*(__be32 *)ptr);
-}
-
-#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
-
-#ifdef __KERNEL__
-
-/*
- * get client id from packed copy.
- *
- * this hack is here because the xlog_pack code copies four bytes
- * of xlog_op_header containing the fields oh_clientid, oh_flags
- * and oh_res2 into the packed copy.
- *
- * later on this four byte chunk is treated as an int and the
- * client id is pulled out.
- *
- * this has endian issues, of course.
- */
-static inline uint xlog_get_client_id(__be32 i)
-{
- return be32_to_cpu(i) >> 24;
-}
-
-/*
- * In core log state
- */
-#define XLOG_STATE_ACTIVE 0x0001 /* Current IC log being written to */
-#define XLOG_STATE_WANT_SYNC 0x0002 /* Want to sync this iclog; no more writes */
-#define XLOG_STATE_SYNCING 0x0004 /* This IC log is syncing */
-#define XLOG_STATE_DONE_SYNC 0x0008 /* Done syncing to disk */
-#define XLOG_STATE_DO_CALLBACK \
- 0x0010 /* Process callback functions */
-#define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */
-#define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/
-#define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */
-#define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */
-#define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */
-#endif /* __KERNEL__ */
-
-/*
- * Flags to log operation header
- *
- * The first write of a new transaction will be preceded with a start
- * record, XLOG_START_TRANS. Once a transaction is committed, a commit
- * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into
- * the remainder of the current active in-core log, it is split up into
- * multiple regions. Each partial region will be marked with a
- * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS.
- *
- */
-#define XLOG_START_TRANS 0x01 /* Start a new transaction */
-#define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */
-#define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */
-#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */
-#define XLOG_END_TRANS 0x10 /* End a continued transaction */
-#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */
-
-#ifdef __KERNEL__
-/*
- * Flags to log ticket
- */
-#define XLOG_TIC_INITED 0x1 /* has been initialized */
-#define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */
-
-#define XLOG_TIC_FLAGS \
- { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \
- { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }
-
-#endif /* __KERNEL__ */
-
-#define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */
-
-/*
- * Flags for log structure
- */
-#define XLOG_ACTIVE_RECOVERY 0x2 /* in the middle of recovery */
-#define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */
-#define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being
- shutdown */
-#define XLOG_TAIL_WARN 0x10 /* log tail verify warning issued */
-
-typedef __uint32_t xlog_tid_t;
-
-#ifdef __KERNEL__
-/*
- * Below are states for covering allocation transactions.
- * By covering, we mean changing the h_tail_lsn in the last on-disk
- * log write such that no allocation transactions will be re-done during
- * recovery after a system crash. Recovery starts at the last on-disk
- * log write.
- *
- * These states are used to insert dummy log entries to cover
- * space allocation transactions which can undo non-transactional changes
- * after a crash. Writes to a file with space
- * already allocated do not result in any transactions. Allocations
- * might include space beyond the EOF. So if we just push the EOF a
- * little, the last transaction for the file could contain the wrong
- * size. If there is no file system activity, after an allocation
- * transaction, and the system crashes, the allocation transaction
- * will get replayed and the file will be truncated. This could
- * be hours/days/... after the allocation occurred.
- *
- * The fix for this is to do two dummy transactions when the
- * system is idle. We need two dummy transaction because the h_tail_lsn
- * in the log record header needs to point beyond the last possible
- * non-dummy transaction. The first dummy changes the h_tail_lsn to
- * the first transaction before the dummy. The second dummy causes
- * h_tail_lsn to point to the first dummy. Recovery starts at h_tail_lsn.
- *
- * These dummy transactions get committed when everything
- * is idle (after there has been some activity).
- *
- * There are 5 states used to control this.
- *
- * IDLE -- no logging has been done on the file system or
- * we are done covering previous transactions.
- * NEED -- logging has occurred and we need a dummy transaction
- * when the log becomes idle.
- * DONE -- we were in the NEED state and have committed a dummy
- * transaction.
- * NEED2 -- we detected that a dummy transaction has gone to the
- * on disk log with no other transactions.
- * DONE2 -- we committed a dummy transaction when in the NEED2 state.
- *
- * There are two places where we switch states:
- *
- * 1.) In xfs_sync, when we detect an idle log and are in NEED or NEED2.
- * We commit the dummy transaction and switch to DONE or DONE2,
- * respectively. In all other states, we don't do anything.
- *
- * 2.) When we finish writing the on-disk log (xlog_state_clean_log).
- *
- * No matter what state we are in, if this isn't the dummy
- * transaction going out, the next state is NEED.
- * So, if we aren't in the DONE or DONE2 states, the next state
- * is NEED. We can't be finishing a write of the dummy record
- * unless it was committed and the state switched to DONE or DONE2.
- *
- * If we are in the DONE state and this was a write of the
- * dummy transaction, we move to NEED2.
- *
- * If we are in the DONE2 state and this was a write of the
- * dummy transaction, we move to IDLE.
- *
- *
- * Writing only one dummy transaction can get appended to
- * one file space allocation. When this happens, the log recovery
- * code replays the space allocation and a file could be truncated.
- * This is why we have the NEED2 and DONE2 states before going idle.
- */
-
-#define XLOG_STATE_COVER_IDLE 0
-#define XLOG_STATE_COVER_NEED 1
-#define XLOG_STATE_COVER_DONE 2
-#define XLOG_STATE_COVER_NEED2 3
-#define XLOG_STATE_COVER_DONE2 4
-
-#define XLOG_COVER_OPS 5
-
-
-/* Ticket reservation region accounting */
-#define XLOG_TIC_LEN_MAX 15
-
-/*
- * Reservation region
- * As would be stored in xfs_log_iovec but without the i_addr which
- * we don't care about.
- */
-typedef struct xlog_res {
- uint r_len; /* region length :4 */
- uint r_type; /* region's transaction type :4 */
-} xlog_res_t;
-
-typedef struct xlog_ticket {
- struct list_head t_queue; /* reserve/write queue */
- struct task_struct *t_task; /* task that owns this ticket */
- xlog_tid_t t_tid; /* transaction identifier : 4 */
- atomic_t t_ref; /* ticket reference count : 4 */
- int t_curr_res; /* current reservation in bytes : 4 */
- int t_unit_res; /* unit reservation in bytes : 4 */
- char t_ocnt; /* original count : 1 */
- char t_cnt; /* current count : 1 */
- char t_clientid; /* who does this belong to; : 1 */
- char t_flags; /* properties of reservation : 1 */
- uint t_trans_type; /* transaction type : 4 */
-
- /* reservation array fields */
- uint t_res_num; /* num in array : 4 */
- uint t_res_num_ophdrs; /* num op hdrs : 4 */
- uint t_res_arr_sum; /* array sum : 4 */
- uint t_res_o_flow; /* sum overflow : 4 */
- xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */
-} xlog_ticket_t;
-
-#endif
-
-
-typedef struct xlog_op_header {
- __be32 oh_tid; /* transaction id of operation : 4 b */
- __be32 oh_len; /* bytes in data region : 4 b */
- __u8 oh_clientid; /* who sent me this : 1 b */
- __u8 oh_flags; /* : 1 b */
- __u16 oh_res2; /* 32 bit align : 2 b */
-} xlog_op_header_t;
-
-
-/* valid values for h_fmt */
-#define XLOG_FMT_UNKNOWN 0
-#define XLOG_FMT_LINUX_LE 1
-#define XLOG_FMT_LINUX_BE 2
-#define XLOG_FMT_IRIX_BE 3
-
-/* our fmt */
-#ifdef XFS_NATIVE_HOST
-#define XLOG_FMT XLOG_FMT_LINUX_BE
-#else
-#define XLOG_FMT XLOG_FMT_LINUX_LE
-#endif
-
-typedef struct xlog_rec_header {
- __be32 h_magicno; /* log record (LR) identifier : 4 */
- __be32 h_cycle; /* write cycle of log : 4 */
- __be32 h_version; /* LR version : 4 */
- __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */
- __be64 h_lsn; /* lsn of this LR : 8 */
- __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
- __le32 h_crc; /* crc of log record : 4 */
- __be32 h_prev_block; /* block number to previous LR : 4 */
- __be32 h_num_logops; /* number of log operations in this LR : 4 */
- __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
- /* new fields */
- __be32 h_fmt; /* format of log record : 4 */
- uuid_t h_fs_uuid; /* uuid of FS : 16 */
- __be32 h_size; /* iclog size : 4 */
-} xlog_rec_header_t;
-
-typedef struct xlog_rec_ext_header {
- __be32 xh_cycle; /* write cycle of log : 4 */
- __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
-} xlog_rec_ext_header_t;
-
-#ifdef __KERNEL__
-
-/*
- * Quite misnamed, because this union lays out the actual on-disk log buffer.
- */
-typedef union xlog_in_core2 {
- xlog_rec_header_t hic_header;
- xlog_rec_ext_header_t hic_xheader;
- char hic_sector[XLOG_HEADER_SIZE];
-} xlog_in_core_2_t;
-
-/*
- * - A log record header is 512 bytes. There is plenty of room to grow the
- * xlog_rec_header_t into the reserved space.
- * - ic_data follows, so a write to disk can start at the beginning of
- * the iclog.
- * - ic_forcewait is used to implement synchronous forcing of the iclog to disk.
- * - ic_next is the pointer to the next iclog in the ring.
- * - ic_bp is a pointer to the buffer used to write this incore log to disk.
- * - ic_log is a pointer back to the global log structure.
- * - ic_callback is a linked list of callback function/argument pairs to be
- * called after an iclog finishes writing.
- * - ic_size is the full size of the header plus data.
- * - ic_offset is the current number of bytes written to in this iclog.
- * - ic_refcnt is bumped when someone is writing to the log.
- * - ic_state is the state of the iclog.
- *
- * Because of cacheline contention on large machines, we need to separate
- * various resources onto different cachelines. To start with, make the
- * structure cacheline aligned. The following fields can be contended on
- * by independent processes:
- *
- * - ic_callback_*
- * - ic_refcnt
- * - fields protected by the global l_icloglock
- *
- * so we need to ensure that these fields are located in separate cachelines.
- * We'll put all the read-only and l_icloglock fields in the first cacheline,
- * and move everything else out to subsequent cachelines.
- */
-typedef struct xlog_in_core {
- wait_queue_head_t ic_force_wait;
- wait_queue_head_t ic_write_wait;
- struct xlog_in_core *ic_next;
- struct xlog_in_core *ic_prev;
- struct xfs_buf *ic_bp;
- struct xlog *ic_log;
- int ic_size;
- int ic_offset;
- int ic_bwritecnt;
- unsigned short ic_state;
- char *ic_datap; /* pointer to iclog data */
-
- /* Callback structures need their own cacheline */
- spinlock_t ic_callback_lock ____cacheline_aligned_in_smp;
- xfs_log_callback_t *ic_callback;
- xfs_log_callback_t **ic_callback_tail;
-
- /* reference counts need their own cacheline */
- atomic_t ic_refcnt ____cacheline_aligned_in_smp;
- xlog_in_core_2_t *ic_data;
-#define ic_header ic_data->hic_header
-} xlog_in_core_t;
-
-/*
- * The CIL context is used to aggregate per-transaction details as well be
- * passed to the iclog for checkpoint post-commit processing. After being
- * passed to the iclog, another context needs to be allocated for tracking the
- * next set of transactions to be aggregated into a checkpoint.
- */
-struct xfs_cil;
-
-struct xfs_cil_ctx {
- struct xfs_cil *cil;
- xfs_lsn_t sequence; /* chkpt sequence # */
- xfs_lsn_t start_lsn; /* first LSN of chkpt commit */
- xfs_lsn_t commit_lsn; /* chkpt commit record lsn */
- struct xlog_ticket *ticket; /* chkpt ticket */
- int nvecs; /* number of regions */
- int space_used; /* aggregate size of regions */
- struct list_head busy_extents; /* busy extents in chkpt */
- struct xfs_log_vec *lv_chain; /* logvecs being pushed */
- xfs_log_callback_t log_cb; /* completion callback hook. */
- struct list_head committing; /* ctx committing list */
-};
-
-/*
- * Committed Item List structure
- *
- * This structure is used to track log items that have been committed but not
- * yet written into the log. It is used only when the delayed logging mount
- * option is enabled.
- *
- * This structure tracks the list of committing checkpoint contexts so
- * we can avoid the problem of having to hold out new transactions during a
- * flush until we have a the commit record LSN of the checkpoint. We can
- * traverse the list of committing contexts in xlog_cil_push_lsn() to find a
- * sequence match and extract the commit LSN directly from there. If the
- * checkpoint is still in the process of committing, we can block waiting for
- * the commit LSN to be determined as well. This should make synchronous
- * operations almost as efficient as the old logging methods.
- */
-struct xfs_cil {
- struct xlog *xc_log;
- struct list_head xc_cil;
- spinlock_t xc_cil_lock;
- struct xfs_cil_ctx *xc_ctx;
- struct rw_semaphore xc_ctx_lock;
- struct list_head xc_committing;
- wait_queue_head_t xc_commit_wait;
- xfs_lsn_t xc_current_sequence;
- struct work_struct xc_push_work;
- xfs_lsn_t xc_push_seq;
-};
-
-/*
- * The amount of log space we allow the CIL to aggregate is difficult to size.
- * Whatever we choose, we have to make sure we can get a reservation for the
- * log space effectively, that it is large enough to capture sufficient
- * relogging to reduce log buffer IO significantly, but it is not too large for
- * the log or induces too much latency when writing out through the iclogs. We
- * track both space consumed and the number of vectors in the checkpoint
- * context, so we need to decide which to use for limiting.
- *
- * Every log buffer we write out during a push needs a header reserved, which
- * is at least one sector and more for v2 logs. Hence we need a reservation of
- * at least 512 bytes per 32k of log space just for the LR headers. That means
- * 16KB of reservation per megabyte of delayed logging space we will consume,
- * plus various headers. The number of headers will vary based on the num of
- * io vectors, so limiting on a specific number of vectors is going to result
- * in transactions of varying size. IOWs, it is more consistent to track and
- * limit space consumed in the log rather than by the number of objects being
- * logged in order to prevent checkpoint ticket overruns.
- *
- * Further, use of static reservations through the log grant mechanism is
- * problematic. It introduces a lot of complexity (e.g. reserve grant vs write
- * grant) and a significant deadlock potential because regranting write space
- * can block on log pushes. Hence if we have to regrant log space during a log
- * push, we can deadlock.
- *
- * However, we can avoid this by use of a dynamic "reservation stealing"
- * technique during transaction commit whereby unused reservation space in the
- * transaction ticket is transferred to the CIL ctx commit ticket to cover the
- * space needed by the checkpoint transaction. This means that we never need to
- * specifically reserve space for the CIL checkpoint transaction, nor do we
- * need to regrant space once the checkpoint completes. This also means the
- * checkpoint transaction ticket is specific to the checkpoint context, rather
- * than the CIL itself.
- *
- * With dynamic reservations, we can effectively make up arbitrary limits for
- * the checkpoint size so long as they don't violate any other size rules.
- * Recovery imposes a rule that no transaction exceed half the log, so we are
- * limited by that. Furthermore, the log transaction reservation subsystem
- * tries to keep 25% of the log free, so we need to keep below that limit or we
- * risk running out of free log space to start any new transactions.
- *
- * In order to keep background CIL push efficient, we will set a lower
- * threshold at which background pushing is attempted without blocking current
- * transaction commits. A separate, higher bound defines when CIL pushes are
- * enforced to ensure we stay within our maximum checkpoint size bounds.
- * threshold, yet give us plenty of space for aggregation on large logs.
- */
-#define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3)
-#define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4))
-
-/*
- * ticket grant locks, queues and accounting have their own cachlines
- * as these are quite hot and can be operated on concurrently.
- */
-struct xlog_grant_head {
- spinlock_t lock ____cacheline_aligned_in_smp;
- struct list_head waiters;
- atomic64_t grant;
-};
-
-/*
- * The reservation head lsn is not made up of a cycle number and block number.
- * Instead, it uses a cycle number and byte number. Logs don't expect to
- * overflow 31 bits worth of byte offset, so using a byte number will mean
- * that round off problems won't occur when releasing partial reservations.
- */
-struct xlog {
- /* The following fields don't need locking */
- struct xfs_mount *l_mp; /* mount point */
- struct xfs_ail *l_ailp; /* AIL log is working with */
- struct xfs_cil *l_cilp; /* CIL log is working with */
- struct xfs_buf *l_xbuf; /* extra buffer for log
- * wrapping */
- struct xfs_buftarg *l_targ; /* buftarg of log */
- struct delayed_work l_work; /* background flush work */
- uint l_flags;
- uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
- struct list_head *l_buf_cancel_table;
- int l_iclog_hsize; /* size of iclog header */
- int l_iclog_heads; /* # of iclog header sectors */
- uint l_sectBBsize; /* sector size in BBs (2^n) */
- int l_iclog_size; /* size of log in bytes */
- int l_iclog_size_log; /* log power size of log */
- int l_iclog_bufs; /* number of iclog buffers */
- xfs_daddr_t l_logBBstart; /* start block of log */
- int l_logsize; /* size of log in bytes */
- int l_logBBsize; /* size of log in BB chunks */
-
- /* The following block of fields are changed while holding icloglock */
- wait_queue_head_t l_flush_wait ____cacheline_aligned_in_smp;
- /* waiting for iclog flush */
- int l_covered_state;/* state of "covering disk
- * log entries" */
- xlog_in_core_t *l_iclog; /* head log queue */
- spinlock_t l_icloglock; /* grab to change iclog state */
- int l_curr_cycle; /* Cycle number of log writes */
- int l_prev_cycle; /* Cycle number before last
- * block increment */
- int l_curr_block; /* current logical log block */
- int l_prev_block; /* previous logical log block */
-
- /*
- * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and
- * read without needing to hold specific locks. To avoid operations
- * contending with other hot objects, place each of them on a separate
- * cacheline.
- */
- /* lsn of last LR on disk */
- atomic64_t l_last_sync_lsn ____cacheline_aligned_in_smp;
- /* lsn of 1st LR with unflushed * buffers */
- atomic64_t l_tail_lsn ____cacheline_aligned_in_smp;
-
- struct xlog_grant_head l_reserve_head;
- struct xlog_grant_head l_write_head;
-
- /* The following field are used for debugging; need to hold icloglock */
-#ifdef DEBUG
- char *l_iclog_bak[XLOG_MAX_ICLOGS];
-#endif
-
-};
-
-#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \
- ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE))
-
-#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
-
-/* common routines */
-extern int
-xlog_recover(
- struct xlog *log);
-extern int
-xlog_recover_finish(
- struct xlog *log);
-
-extern __le32 xlog_cksum(struct xlog *log, struct xlog_rec_header *rhead,
- char *dp, int size);
-
-extern kmem_zone_t *xfs_log_ticket_zone;
-struct xlog_ticket *
-xlog_ticket_alloc(
- struct xlog *log,
- int unit_bytes,
- int count,
- char client,
- bool permanent,
- xfs_km_flags_t alloc_flags);
-
-
-static inline void
-xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes)
-{
- *ptr += bytes;
- *len -= bytes;
- *off += bytes;
-}
-
-void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
-int
-xlog_write(
- struct xlog *log,
- struct xfs_log_vec *log_vector,
- struct xlog_ticket *tic,
- xfs_lsn_t *start_lsn,
- struct xlog_in_core **commit_iclog,
- uint flags);
-
-/*
- * When we crack an atomic LSN, we sample it first so that the value will not
- * change while we are cracking it into the component values. This means we
- * will always get consistent component values to work from. This should always
- * be used to sample and crack LSNs that are stored and updated in atomic
- * variables.
- */
-static inline void
-xlog_crack_atomic_lsn(atomic64_t *lsn, uint *cycle, uint *block)
-{
- xfs_lsn_t val = atomic64_read(lsn);
-
- *cycle = CYCLE_LSN(val);
- *block = BLOCK_LSN(val);
-}
-
-/*
- * Calculate and assign a value to an atomic LSN variable from component pieces.
- */
-static inline void
-xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block)
-{
- atomic64_set(lsn, xlog_assign_lsn(cycle, block));
-}
-
-/*
- * When we crack the grant head, we sample it first so that the value will not
- * change while we are cracking it into the component values. This means we
- * will always get consistent component values to work from.
- */
-static inline void
-xlog_crack_grant_head_val(int64_t val, int *cycle, int *space)
-{
- *cycle = val >> 32;
- *space = val & 0xffffffff;
-}
-
-static inline void
-xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space)
-{
- xlog_crack_grant_head_val(atomic64_read(head), cycle, space);
-}
-
-static inline int64_t
-xlog_assign_grant_head_val(int cycle, int space)
-{
- return ((int64_t)cycle << 32) | space;
-}
-
-static inline void
-xlog_assign_grant_head(atomic64_t *head, int cycle, int space)
-{
- atomic64_set(head, xlog_assign_grant_head_val(cycle, space));
-}
-
-/*
- * Committed Item List interfaces
- */
-int
-xlog_cil_init(struct xlog *log);
-void
-xlog_cil_init_post_recovery(struct xlog *log);
-void
-xlog_cil_destroy(struct xlog *log);
-
-/*
- * CIL force routines
- */
-xfs_lsn_t
-xlog_cil_force_lsn(
- struct xlog *log,
- xfs_lsn_t sequence);
-
-static inline void
-xlog_cil_force(struct xlog *log)
-{
- xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence);
-}
-
-/*
- * Unmount record type is used as a pseudo transaction type for the ticket.
- * It's value must be outside the range of XFS_TRANS_* values.
- */
-#define XLOG_UNMOUNT_REC_TYPE (-1U)
-
-/*
- * Wrapper function for waiting on a wait queue serialised against wakeups
- * by a spinlock. This matches the semantics of all the wait queues used in the
- * log code.
- */
-static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue_exclusive(wq, &wait);
- __set_current_state(TASK_UNINTERRUPTIBLE);
- spin_unlock(lock);
- schedule();
- remove_wait_queue(wq, &wait);
-}
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_LOG_PRIV_H__ */
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 93beb23..92a90f1 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -17,8 +17,6 @@
*/
#include <xfs/libxfs.h>
-#include <xfs/xfs_log.h>
-#include <xfs/xfs_log_priv.h>
#include "init.h"
#define BDSTRAT_SIZE (256 * 1024)
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index 7f5a41c..13ca327 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -26,6 +26,7 @@
(0); \
})
+#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
/*
* Verify the given count of basic blocks is valid number of blocks
@@ -1032,6 +1033,8 @@ xlog_recover_add_item(
list_add_tail(&item->ri_list, head);
}
+#define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
+
STATIC int
xlog_recover_add_to_cont_trans(
struct xlog *log,
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 17/49] xfs: split out inode log item format definition
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (15 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 16/49] xfs: separate out log format definitions Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-03 15:23 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 18/49] xfs: split out buf log item format definitions Dave Chinner
` (32 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Th elog item format definitions are shared with userspace. split the
out of header files that contain kernel only defintions to make it
simple to shared them.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 4 +-
include/libxfs.h | 5 +-
include/libxlog.h | 1 -
include/xfs_inode.h | 70 ------------------
include/xfs_inode_item.h | 170 ------------------------------------------
include/xfs_log_format.h | 189 +++++++++++++++++++++++++++++++++++++++++++++++
include/xfs_types.h | 6 ++
libxfs/trans.c | 2 +-
8 files changed, 202 insertions(+), 245 deletions(-)
delete mode 100644 include/xfs_inode_item.h
diff --git a/include/Makefile b/include/Makefile
index efa3275..722aef3 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -26,7 +26,9 @@ QAHFILES = libxfs.h libxlog.h \
xfs_btree_trace.h xfs_buf_item.h xfs_cksum.h xfs_da_btree.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \
- xfs_icreate_item.h xfs_inode.h xfs_inode_item.h xfs_inum.h \
+ xfs_icreate_item.h \
+ xfs_inode.h \
+ xfs_inum.h \
xfs_log_format.h \
xfs_log_recover.h \
xfs_metadump.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index c9918cd..c96857b 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -36,6 +36,9 @@
#include <xfs/xfs_types.h>
#include <xfs/xfs_fs.h>
#include <xfs/xfs_arch.h>
+
+#include <xfs/xfs_log_format.h>
+
#include <xfs/xfs_bit.h>
#include <xfs/xfs_inum.h>
#include <xfs/xfs_sb.h>
@@ -50,7 +53,6 @@
#include <xfs/xfs_dinode.h>
#include <xfs/xfs_inode.h>
#include <xfs/xfs_buf_item.h>
-#include <xfs/xfs_inode_item.h>
#include <xfs/xfs_alloc.h>
#include <xfs/xfs_btree.h>
#include <xfs/xfs_btree_trace.h>
@@ -59,7 +61,6 @@
#include <xfs/xfs_symlink.h>
#include <xfs/xfs_icreate_item.h>
-#include <xfs/xfs_log_format.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/include/libxlog.h b/include/libxlog.h
index 961c4b5..301e3dd 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -49,7 +49,6 @@ struct xlog {
#include <xfs/xfs_log_recover.h>
#include <xfs/xfs_buf_item.h>
-#include <xfs/xfs_inode_item.h>
#include <xfs/xfs_extfree_item.h>
#include <xfs/xfs_icreate_item.h>
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index fdca7f7..1e92338 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -23,12 +23,6 @@ struct xfs_dinode;
struct xfs_inode;
/*
- * Fork identifiers.
- */
-#define XFS_DATA_FORK 0
-#define XFS_ATTR_FORK 1
-
-/*
* The following xfs_ext_irec_t struct introduces a second (top) level
* to the in-core extent allocation scheme. These structs are allocated
* in a contiguous block, creating an indirection array where each entry
@@ -113,69 +107,6 @@ struct xfs_imap {
* i_mnext and i_mprev fields, it is used as a marker in the inode
* chain off the mount structure by xfs_sync calls.
*/
-
-typedef struct xfs_ictimestamp {
- __int32_t t_sec; /* timestamp seconds */
- __int32_t t_nsec; /* timestamp nanoseconds */
-} xfs_ictimestamp_t;
-
-/*
- * NOTE: This structure must be kept identical to struct xfs_dinode
- * in xfs_dinode.h except for the endianness annotations.
- */
-typedef struct xfs_icdinode {
- __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
- __uint16_t di_mode; /* mode and type of file */
- __int8_t di_version; /* inode version */
- __int8_t di_format; /* format of di_c data */
- __uint16_t di_onlink; /* old number of links to file */
- __uint32_t di_uid; /* owner's user id */
- __uint32_t di_gid; /* owner's group id */
- __uint32_t di_nlink; /* number of links to file */
- __uint16_t di_projid_lo; /* lower part of owner's project id */
- __uint16_t di_projid_hi; /* higher part of owner's project id */
- __uint8_t di_pad[6]; /* unused, zeroed space */
- __uint16_t di_flushiter; /* incremented on flush */
- xfs_ictimestamp_t di_atime; /* time last accessed */
- xfs_ictimestamp_t di_mtime; /* time last modified */
- xfs_ictimestamp_t di_ctime; /* time created/inode modified */
- xfs_fsize_t di_size; /* number of bytes in file */
- xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
- xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- xfs_extnum_t di_nextents; /* number of extents in data fork */
- xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
- __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
- __int8_t di_aformat; /* format of attr fork's data */
- __uint32_t di_dmevmask; /* DMIG event mask */
- __uint16_t di_dmstate; /* DMIG state info */
- __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
- __uint32_t di_gen; /* generation number */
-
- /* di_next_unlinked is the only non-core field in the old dinode */
- __be32 di_next_unlinked;/* agi unlinked list ptr */
-
- /* start of the extended dinode, writable fields */
- __uint32_t di_crc; /* CRC of the inode */
- __uint64_t di_changecount; /* number of attribute changes */
- xfs_lsn_t di_lsn; /* flush sequence */
- __uint64_t di_flags2; /* more random flags */
- __uint8_t di_pad2[16]; /* more padding for future expansion */
-
- /* fields only written to during inode creation */
- xfs_ictimestamp_t di_crtime; /* time created */
- xfs_ino_t di_ino; /* inode number */
- uuid_t di_uuid; /* UUID of the filesystem */
-
- /* structure must be padded to 64 bit alignment */
-} xfs_icdinode_t;
-
-static inline uint xfs_icdinode_size(int version)
-{
- if (version == 3)
- return sizeof(struct xfs_icdinode);
- return offsetof(struct xfs_icdinode, di_next_unlinked);
-}
-
/*
* Flags for xfs_ichgtime().
*/
@@ -625,7 +556,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
extern struct kmem_zone *xfs_ifork_zone;
extern struct kmem_zone *xfs_inode_zone;
-extern struct kmem_zone *xfs_ili_zone;
extern const struct xfs_buf_ops xfs_inode_buf_ops;
#endif /* __XFS_INODE_H__ */
diff --git a/include/xfs_inode_item.h b/include/xfs_inode_item.h
deleted file mode 100644
index 779812f..0000000
--- a/include/xfs_inode_item.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_INODE_ITEM_H__
-#define __XFS_INODE_ITEM_H__
-
-/*
- * This is the structure used to lay out an inode log item in the
- * log. The size of the inline data/extents/b-tree root to be logged
- * (if any) is indicated in the ilf_dsize field. Changes to this structure
- * must be added on to the end.
- */
-typedef struct xfs_inode_log_format {
- __uint16_t ilf_type; /* inode log item type */
- __uint16_t ilf_size; /* size of this item */
- __uint32_t ilf_fields; /* flags for fields logged */
- __uint16_t ilf_asize; /* size of attr d/ext/root */
- __uint16_t ilf_dsize; /* size of data/ext/root */
- __uint64_t ilf_ino; /* inode number */
- union {
- __uint32_t ilfu_rdev; /* rdev value for dev inode*/
- uuid_t ilfu_uuid; /* mount point value */
- } ilf_u;
- __int64_t ilf_blkno; /* blkno of inode buffer */
- __int32_t ilf_len; /* len of inode buffer */
- __int32_t ilf_boffset; /* off of inode in buffer */
-} xfs_inode_log_format_t;
-
-typedef struct xfs_inode_log_format_32 {
- __uint16_t ilf_type; /* inode log item type */
- __uint16_t ilf_size; /* size of this item */
- __uint32_t ilf_fields; /* flags for fields logged */
- __uint16_t ilf_asize; /* size of attr d/ext/root */
- __uint16_t ilf_dsize; /* size of data/ext/root */
- __uint64_t ilf_ino; /* inode number */
- union {
- __uint32_t ilfu_rdev; /* rdev value for dev inode*/
- uuid_t ilfu_uuid; /* mount point value */
- } ilf_u;
- __int64_t ilf_blkno; /* blkno of inode buffer */
- __int32_t ilf_len; /* len of inode buffer */
- __int32_t ilf_boffset; /* off of inode in buffer */
-} __attribute__((packed)) xfs_inode_log_format_32_t;
-
-typedef struct xfs_inode_log_format_64 {
- __uint16_t ilf_type; /* inode log item type */
- __uint16_t ilf_size; /* size of this item */
- __uint32_t ilf_fields; /* flags for fields logged */
- __uint16_t ilf_asize; /* size of attr d/ext/root */
- __uint16_t ilf_dsize; /* size of data/ext/root */
- __uint32_t ilf_pad; /* pad for 64 bit boundary */
- __uint64_t ilf_ino; /* inode number */
- union {
- __uint32_t ilfu_rdev; /* rdev value for dev inode*/
- uuid_t ilfu_uuid; /* mount point value */
- } ilf_u;
- __int64_t ilf_blkno; /* blkno of inode buffer */
- __int32_t ilf_len; /* len of inode buffer */
- __int32_t ilf_boffset; /* off of inode in buffer */
-} xfs_inode_log_format_64_t;
-
-/*
- * Flags for xfs_trans_log_inode flags field.
- */
-#define XFS_ILOG_CORE 0x001 /* log standard inode fields */
-#define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */
-#define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */
-#define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */
-#define XFS_ILOG_DEV 0x010 /* log the dev field */
-#define XFS_ILOG_UUID 0x020 /* log the uuid field */
-#define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */
-#define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */
-#define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */
-
-
-/*
- * The timestamps are dirty, but not necessarily anything else in the inode
- * core. Unlike the other fields above this one must never make it to disk
- * in the ilf_fields of the inode_log_format, but is purely store in-memory in
- * ili_fields in the inode_log_item.
- */
-#define XFS_ILOG_TIMESTAMP 0x4000
-
-#define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
- XFS_ILOG_DBROOT | XFS_ILOG_DEV | \
- XFS_ILOG_UUID | XFS_ILOG_ADATA | \
- XFS_ILOG_AEXT | XFS_ILOG_ABROOT)
-
-#define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
- XFS_ILOG_DBROOT)
-
-#define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
- XFS_ILOG_ABROOT)
-
-#define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \
- XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \
- XFS_ILOG_DEV | XFS_ILOG_UUID | \
- XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
- XFS_ILOG_ABROOT | XFS_ILOG_TIMESTAMP)
-
-static inline int xfs_ilog_fbroot(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
-}
-
-static inline int xfs_ilog_fext(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT);
-}
-
-static inline int xfs_ilog_fdata(int w)
-{
- return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA);
-}
-
-#ifdef __KERNEL__
-
-struct xfs_buf;
-struct xfs_bmbt_rec;
-struct xfs_inode;
-struct xfs_mount;
-
-
-typedef struct xfs_inode_log_item {
- xfs_log_item_t ili_item; /* common portion */
- struct xfs_inode *ili_inode; /* inode ptr */
- xfs_lsn_t ili_flush_lsn; /* lsn at last flush */
- xfs_lsn_t ili_last_lsn; /* lsn at last transaction */
- unsigned short ili_lock_flags; /* lock flags */
- unsigned short ili_logged; /* flushed logged data */
- unsigned int ili_last_fields; /* fields when flushed */
- unsigned int ili_fields; /* fields to be logged */
- struct xfs_bmbt_rec *ili_extents_buf; /* array of logged
- data exts */
- struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged
- attr exts */
- xfs_inode_log_format_t ili_format; /* logged structure */
-} xfs_inode_log_item_t;
-
-
-static inline int xfs_inode_clean(xfs_inode_t *ip)
-{
- return !ip->i_itemp || !(ip->i_itemp->ili_fields & XFS_ILOG_ALL);
-}
-
-extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
-extern void xfs_inode_item_destroy(struct xfs_inode *);
-extern void xfs_iflush_done(struct xfs_buf *, struct xfs_log_item *);
-extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *);
-extern void xfs_iflush_abort(struct xfs_inode *, bool);
-extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
- xfs_inode_log_format_t *);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_INODE_ITEM_H__ */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index 9f9aeb6..fd46a7f 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -18,6 +18,16 @@
#ifndef __XFS_LOG_FORMAT_H__
#define __XFS_LOG_FORMAT_H__
+/*
+ * On-disk Log Format definitions.
+ *
+ * This file contains all the on-disk format definitions used within the log. It
+ * includes the physical log structure itself, as well as all the log item
+ * format structures that are written into the log and intepreted by log
+ * recovery. We start with the physical log format definitions, and then work
+ * through all the log items definitions and everything they encode into the
+ * log.
+ */
typedef __uint32_t xlog_tid_t;
#define XLOG_MIN_ICLOGS 2
@@ -175,4 +185,183 @@ typedef struct xfs_log_iovec {
uint i_type; /* type of region */
} xfs_log_iovec_t;
+
+/*
+ * Inode Log Item Format definitions.
+ *
+ * This is the structure used to lay out an inode log item in the
+ * log. The size of the inline data/extents/b-tree root to be logged
+ * (if any) is indicated in the ilf_dsize field. Changes to this structure
+ * must be added on to the end.
+ */
+typedef struct xfs_inode_log_format {
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint64_t ilf_ino; /* inode number */
+ union {
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
+ uuid_t ilfu_uuid; /* mount point value */
+ } ilf_u;
+ __int64_t ilf_blkno; /* blkno of inode buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
+} xfs_inode_log_format_t;
+
+typedef struct xfs_inode_log_format_32 {
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint64_t ilf_ino; /* inode number */
+ union {
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
+ uuid_t ilfu_uuid; /* mount point value */
+ } ilf_u;
+ __int64_t ilf_blkno; /* blkno of inode buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
+} __attribute__((packed)) xfs_inode_log_format_32_t;
+
+typedef struct xfs_inode_log_format_64 {
+ __uint16_t ilf_type; /* inode log item type */
+ __uint16_t ilf_size; /* size of this item */
+ __uint32_t ilf_fields; /* flags for fields logged */
+ __uint16_t ilf_asize; /* size of attr d/ext/root */
+ __uint16_t ilf_dsize; /* size of data/ext/root */
+ __uint32_t ilf_pad; /* pad for 64 bit boundary */
+ __uint64_t ilf_ino; /* inode number */
+ union {
+ __uint32_t ilfu_rdev; /* rdev value for dev inode*/
+ uuid_t ilfu_uuid; /* mount point value */
+ } ilf_u;
+ __int64_t ilf_blkno; /* blkno of inode buffer */
+ __int32_t ilf_len; /* len of inode buffer */
+ __int32_t ilf_boffset; /* off of inode in buffer */
+} xfs_inode_log_format_64_t;
+
+/*
+ * Flags for xfs_trans_log_inode flags field.
+ */
+#define XFS_ILOG_CORE 0x001 /* log standard inode fields */
+#define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */
+#define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */
+#define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */
+#define XFS_ILOG_DEV 0x010 /* log the dev field */
+#define XFS_ILOG_UUID 0x020 /* log the uuid field */
+#define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */
+#define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */
+#define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */
+
+
+/*
+ * The timestamps are dirty, but not necessarily anything else in the inode
+ * core. Unlike the other fields above this one must never make it to disk
+ * in the ilf_fields of the inode_log_format, but is purely store in-memory in
+ * ili_fields in the inode_log_item.
+ */
+#define XFS_ILOG_TIMESTAMP 0x4000
+
+#define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
+ XFS_ILOG_DBROOT | XFS_ILOG_DEV | \
+ XFS_ILOG_UUID | XFS_ILOG_ADATA | \
+ XFS_ILOG_AEXT | XFS_ILOG_ABROOT)
+
+#define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
+ XFS_ILOG_DBROOT)
+
+#define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
+ XFS_ILOG_ABROOT)
+
+#define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \
+ XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \
+ XFS_ILOG_DEV | XFS_ILOG_UUID | \
+ XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
+ XFS_ILOG_ABROOT | XFS_ILOG_TIMESTAMP)
+
+static inline int xfs_ilog_fbroot(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
+}
+
+static inline int xfs_ilog_fext(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT);
+}
+
+static inline int xfs_ilog_fdata(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA);
+}
+
+/*
+ * Incore version of the on-disk inode core structures. We log this directly
+ * into the journal in host CPU format (for better or worse) and as such
+ * directly mirrors the xfs_dinode structure as it must contain all the same
+ * information.
+ */
+typedef struct xfs_ictimestamp {
+ __int32_t t_sec; /* timestamp seconds */
+ __int32_t t_nsec; /* timestamp nanoseconds */
+} xfs_ictimestamp_t;
+
+/*
+ * NOTE: This structure must be kept identical to struct xfs_dinode
+ * in xfs_dinode.h except for the endianness annotations.
+ */
+typedef struct xfs_icdinode {
+ __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
+ __uint16_t di_mode; /* mode and type of file */
+ __int8_t di_version; /* inode version */
+ __int8_t di_format; /* format of di_c data */
+ __uint16_t di_onlink; /* old number of links to file */
+ __uint32_t di_uid; /* owner's user id */
+ __uint32_t di_gid; /* owner's group id */
+ __uint32_t di_nlink; /* number of links to file */
+ __uint16_t di_projid_lo; /* lower part of owner's project id */
+ __uint16_t di_projid_hi; /* higher part of owner's project id */
+ __uint8_t di_pad[6]; /* unused, zeroed space */
+ __uint16_t di_flushiter; /* incremented on flush */
+ xfs_ictimestamp_t di_atime; /* time last accessed */
+ xfs_ictimestamp_t di_mtime; /* time last modified */
+ xfs_ictimestamp_t di_ctime; /* time created/inode modified */
+ xfs_fsize_t di_size; /* number of bytes in file */
+ xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
+ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
+ xfs_extnum_t di_nextents; /* number of extents in data fork */
+ xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
+ __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
+ __int8_t di_aformat; /* format of attr fork's data */
+ __uint32_t di_dmevmask; /* DMIG event mask */
+ __uint16_t di_dmstate; /* DMIG state info */
+ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
+ __uint32_t di_gen; /* generation number */
+
+ /* di_next_unlinked is the only non-core field in the old dinode */
+ xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
+
+ /* start of the extended dinode, writable fields */
+ __uint32_t di_crc; /* CRC of the inode */
+ __uint64_t di_changecount; /* number of attribute changes */
+ xfs_lsn_t di_lsn; /* flush sequence */
+ __uint64_t di_flags2; /* more random flags */
+ __uint8_t di_pad2[16]; /* more padding for future expansion */
+
+ /* fields only written to during inode creation */
+ xfs_ictimestamp_t di_crtime; /* time created */
+ xfs_ino_t di_ino; /* inode number */
+ uuid_t di_uuid; /* UUID of the filesystem */
+
+ /* structure must be padded to 64 bit alignment */
+} xfs_icdinode_t;
+
+static inline uint xfs_icdinode_size(int version)
+{
+ if (version == 3)
+ return sizeof(struct xfs_icdinode);
+ return offsetof(struct xfs_icdinode, di_next_unlinked);
+}
#endif /* __XFS_LOG_FORMAT_H__ */
diff --git a/include/xfs_types.h b/include/xfs_types.h
index dd6bf71..543fdf0 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -147,6 +147,12 @@ typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */
#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG)
/*
+ * Inode fork identifiers.
+ */
+#define XFS_DATA_FORK 0
+#define XFS_ATTR_FORK 1
+
+/*
* Min numbers of data/attr fork btree root pointers.
*/
#define MINDBTPTRS 3
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 97220e7..645952c 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -226,7 +226,7 @@ libxfs_trans_inode_alloc_buf(
* to be logged when the transaction is committed. The inode must
* already be associated with the given transaction.
*
- * The values for fieldmask are defined in xfs_inode_item.h. We always
+ * The values for fieldmask are defined in xfs_log_format.h. We always
* log all of the core inode if any of it has changed, and we always log
* all of the inline data/extents/b-tree root if any of them has changed.
*/
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 18/49] xfs: split out buf log item format definitions
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (16 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 17/49] xfs: split out inode log item format definition Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-04 23:37 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 19/49] xfs: split out inode log item format definition Dave Chinner
` (31 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 4 +-
include/libxfs.h | 6 +-
include/libxlog.h | 1 -
include/xfs_buf_item.h | 172 -----------------------------------------------
include/xfs_log_format.h | 97 ++++++++++++++++++++++++++
5 files changed, 105 insertions(+), 175 deletions(-)
delete mode 100644 include/xfs_buf_item.h
diff --git a/include/Makefile b/include/Makefile
index 722aef3..f5c50b7 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -23,7 +23,9 @@ QAHFILES = libxfs.h libxlog.h \
swab.h \
xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h xfs_attr_leaf.h \
xfs_attr_sf.h xfs_bit.h xfs_bmap.h xfs_bmap_btree.h xfs_btree.h \
- xfs_btree_trace.h xfs_buf_item.h xfs_cksum.h xfs_da_btree.h \
+ xfs_btree_trace.h \
+ xfs_cksum.h \
+ xfs_da_btree.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \
xfs_icreate_item.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index c96857b..40e5e25 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -52,7 +52,6 @@
#include <xfs/xfs_attr_sf.h>
#include <xfs/xfs_dinode.h>
#include <xfs/xfs_inode.h>
-#include <xfs/xfs_buf_item.h>
#include <xfs/xfs_alloc.h>
#include <xfs/xfs_btree.h>
#include <xfs/xfs_btree_trace.h>
@@ -438,6 +437,11 @@ typedef struct xfs_buf_log_item {
xfs_buf_log_format_t bli_format; /* in-log header */
} xfs_buf_log_item_t;
+#define XFS_BLI_DIRTY (1<<0)
+#define XFS_BLI_HOLD (1<<1)
+#define XFS_BLI_STALE (1<<2)
+#define XFS_BLI_INODE_ALLOC_BUF (1<<3)
+
#include <xfs/xfs_trans.h>
typedef struct xfs_trans {
diff --git a/include/libxlog.h b/include/libxlog.h
index 301e3dd..08f5dbb 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -48,7 +48,6 @@ struct xlog {
};
#include <xfs/xfs_log_recover.h>
-#include <xfs/xfs_buf_item.h>
#include <xfs/xfs_extfree_item.h>
#include <xfs/xfs_icreate_item.h>
diff --git a/include/xfs_buf_item.h b/include/xfs_buf_item.h
deleted file mode 100644
index 2573d2a..0000000
--- a/include/xfs_buf_item.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BUF_ITEM_H__
-#define __XFS_BUF_ITEM_H__
-
-extern kmem_zone_t *xfs_buf_item_zone;
-
-/*
- * This flag indicates that the buffer contains on disk inodes
- * and requires special recovery handling.
- */
-#define XFS_BLF_INODE_BUF (1<<0)
-/*
- * This flag indicates that the buffer should not be replayed
- * during recovery because its blocks are being freed.
- */
-#define XFS_BLF_CANCEL (1<<1)
-
-/*
- * This flag indicates that the buffer contains on disk
- * user or group dquots and may require special recovery handling.
- */
-#define XFS_BLF_UDQUOT_BUF (1<<2)
-#define XFS_BLF_PDQUOT_BUF (1<<3)
-#define XFS_BLF_GDQUOT_BUF (1<<4)
-
-#define XFS_BLF_CHUNK 128
-#define XFS_BLF_SHIFT 7
-#define BIT_TO_WORD_SHIFT 5
-#define NBWORD (NBBY * sizeof(unsigned int))
-
-/*
- * This is the structure used to lay out a buf log item in the
- * log. The data map describes which 128 byte chunks of the buffer
- * have been logged.
- */
-#define XFS_BLF_DATAMAP_SIZE ((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / NBWORD)
-
-typedef struct xfs_buf_log_format {
- unsigned short blf_type; /* buf log item type indicator */
- unsigned short blf_size; /* size of this item */
- ushort blf_flags; /* misc state */
- ushort blf_len; /* number of blocks in this buf */
- __int64_t blf_blkno; /* starting blkno of this buf */
- unsigned int blf_map_size; /* used size of data bitmap in words */
- unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */
-} xfs_buf_log_format_t;
-
-/*
- * All buffers now need to tell recovery where the magic number
- * is so that it can verify and calculate the CRCs on the buffer correctly
- * once the changes have been replayed into the buffer.
- *
- * The type value is held in the upper 5 bits of the blf_flags field, which is
- * an unsigned 16 bit field. Hence we need to shift it 11 bits up and down.
- */
-#define XFS_BLFT_BITS 5
-#define XFS_BLFT_SHIFT 11
-#define XFS_BLFT_MASK (((1 << XFS_BLFT_BITS) - 1) << XFS_BLFT_SHIFT)
-
-enum xfs_blft {
- XFS_BLFT_UNKNOWN_BUF = 0,
- XFS_BLFT_UDQUOT_BUF,
- XFS_BLFT_PDQUOT_BUF,
- XFS_BLFT_GDQUOT_BUF,
- XFS_BLFT_BTREE_BUF,
- XFS_BLFT_AGF_BUF,
- XFS_BLFT_AGFL_BUF,
- XFS_BLFT_AGI_BUF,
- XFS_BLFT_DINO_BUF,
- XFS_BLFT_SYMLINK_BUF,
- XFS_BLFT_DIR_BLOCK_BUF,
- XFS_BLFT_DIR_DATA_BUF,
- XFS_BLFT_DIR_FREE_BUF,
- XFS_BLFT_DIR_LEAF1_BUF,
- XFS_BLFT_DIR_LEAFN_BUF,
- XFS_BLFT_DA_NODE_BUF,
- XFS_BLFT_ATTR_LEAF_BUF,
- XFS_BLFT_ATTR_RMT_BUF,
- XFS_BLFT_SB_BUF,
- XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS),
-};
-
-static inline void
-xfs_blft_to_flags(struct xfs_buf_log_format *blf, enum xfs_blft type)
-{
- ASSERT(type > XFS_BLFT_UNKNOWN_BUF && type < XFS_BLFT_MAX_BUF);
- blf->blf_flags &= ~XFS_BLFT_MASK;
- blf->blf_flags |= ((type << XFS_BLFT_SHIFT) & XFS_BLFT_MASK);
-}
-
-static inline __uint16_t
-xfs_blft_from_flags(struct xfs_buf_log_format *blf)
-{
- return (blf->blf_flags & XFS_BLFT_MASK) >> XFS_BLFT_SHIFT;
-}
-
-/*
- * buf log item flags
- */
-#define XFS_BLI_HOLD 0x01
-#define XFS_BLI_DIRTY 0x02
-#define XFS_BLI_STALE 0x04
-#define XFS_BLI_LOGGED 0x08
-#define XFS_BLI_INODE_ALLOC_BUF 0x10
-#define XFS_BLI_STALE_INODE 0x20
-#define XFS_BLI_INODE_BUF 0x40
-
-#define XFS_BLI_FLAGS \
- { XFS_BLI_HOLD, "HOLD" }, \
- { XFS_BLI_DIRTY, "DIRTY" }, \
- { XFS_BLI_STALE, "STALE" }, \
- { XFS_BLI_LOGGED, "LOGGED" }, \
- { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \
- { XFS_BLI_STALE_INODE, "STALE_INODE" }, \
- { XFS_BLI_INODE_BUF, "INODE_BUF" }
-
-
-#ifdef __KERNEL__
-
-struct xfs_buf;
-struct xfs_mount;
-struct xfs_buf_log_item;
-
-/*
- * This is the in core log item structure used to track information
- * needed to log buffers. It tracks how many times the lock has been
- * locked, and which 128 byte chunks of the buffer are dirty.
- */
-typedef struct xfs_buf_log_item {
- xfs_log_item_t bli_item; /* common item structure */
- struct xfs_buf *bli_buf; /* real buffer pointer */
- unsigned int bli_flags; /* misc flags */
- unsigned int bli_recur; /* lock recursion count */
- atomic_t bli_refcount; /* cnt of tp refs */
- int bli_format_count; /* count of headers */
- struct xfs_buf_log_format *bli_formats; /* array of in-log header ptrs */
- struct xfs_buf_log_format __bli_format; /* embedded in-log header */
-} xfs_buf_log_item_t;
-
-void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
-void xfs_buf_item_relse(struct xfs_buf *);
-void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint);
-uint xfs_buf_item_dirty(xfs_buf_log_item_t *);
-void xfs_buf_attach_iodone(struct xfs_buf *,
- void(*)(struct xfs_buf *, xfs_log_item_t *),
- xfs_log_item_t *);
-void xfs_buf_iodone_callbacks(struct xfs_buf *);
-void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *);
-
-void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
- enum xfs_blft);
-void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp, struct xfs_buf *src_bp);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_BUF_ITEM_H__ */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index fd46a7f..77a6024 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -364,4 +364,101 @@ static inline uint xfs_icdinode_size(int version)
return sizeof(struct xfs_icdinode);
return offsetof(struct xfs_icdinode, di_next_unlinked);
}
+
+/*
+ * Buffer Log Format defintions
+ *
+ * These are the physical dirty bitmap defintions for the log format structure.
+ */
+#define XFS_BLF_CHUNK 128
+#define XFS_BLF_SHIFT 7
+#define BIT_TO_WORD_SHIFT 5
+#define NBWORD (NBBY * sizeof(unsigned int))
+
+/*
+ * This flag indicates that the buffer contains on disk inodes
+ * and requires special recovery handling.
+ */
+#define XFS_BLF_INODE_BUF (1<<0)
+
+/*
+ * This flag indicates that the buffer should not be replayed
+ * during recovery because its blocks are being freed.
+ */
+#define XFS_BLF_CANCEL (1<<1)
+
+/*
+ * This flag indicates that the buffer contains on disk
+ * user or group dquots and may require special recovery handling.
+ */
+#define XFS_BLF_UDQUOT_BUF (1<<2)
+#define XFS_BLF_PDQUOT_BUF (1<<3)
+#define XFS_BLF_GDQUOT_BUF (1<<4)
+
+/*
+ * This is the structure used to lay out a buf log item in the
+ * log. The data map describes which 128 byte chunks of the buffer
+ * have been logged.
+ */
+#define XFS_BLF_DATAMAP_SIZE ((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / NBWORD)
+
+typedef struct xfs_buf_log_format {
+ unsigned short blf_type; /* buf log item type indicator */
+ unsigned short blf_size; /* size of this item */
+ ushort blf_flags; /* misc state */
+ ushort blf_len; /* number of blocks in this buf */
+ __int64_t blf_blkno; /* starting blkno of this buf */
+ unsigned int blf_map_size; /* used size of data bitmap in words */
+ unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */
+} xfs_buf_log_format_t;
+
+/*
+ * All buffers now need to tell recovery where the magic number
+ * is so that it can verify and calculate the CRCs on the buffer correctly
+ * once the changes have been replayed into the buffer.
+ *
+ * The type value is held in the upper 5 bits of the blf_flags field, which is
+ * an unsigned 16 bit field. Hence we need to shift it 11 bits up and down.
+ */
+#define XFS_BLFT_BITS 5
+#define XFS_BLFT_SHIFT 11
+#define XFS_BLFT_MASK (((1 << XFS_BLFT_BITS) - 1) << XFS_BLFT_SHIFT)
+
+enum xfs_blft {
+ XFS_BLFT_UNKNOWN_BUF = 0,
+ XFS_BLFT_UDQUOT_BUF,
+ XFS_BLFT_PDQUOT_BUF,
+ XFS_BLFT_GDQUOT_BUF,
+ XFS_BLFT_BTREE_BUF,
+ XFS_BLFT_AGF_BUF,
+ XFS_BLFT_AGFL_BUF,
+ XFS_BLFT_AGI_BUF,
+ XFS_BLFT_DINO_BUF,
+ XFS_BLFT_SYMLINK_BUF,
+ XFS_BLFT_DIR_BLOCK_BUF,
+ XFS_BLFT_DIR_DATA_BUF,
+ XFS_BLFT_DIR_FREE_BUF,
+ XFS_BLFT_DIR_LEAF1_BUF,
+ XFS_BLFT_DIR_LEAFN_BUF,
+ XFS_BLFT_DA_NODE_BUF,
+ XFS_BLFT_ATTR_LEAF_BUF,
+ XFS_BLFT_ATTR_RMT_BUF,
+ XFS_BLFT_SB_BUF,
+ XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS),
+};
+
+static inline void
+xfs_blft_to_flags(struct xfs_buf_log_format *blf, enum xfs_blft type)
+{
+ ASSERT(type > XFS_BLFT_UNKNOWN_BUF && type < XFS_BLFT_MAX_BUF);
+ blf->blf_flags &= ~XFS_BLFT_MASK;
+ blf->blf_flags |= ((type << XFS_BLFT_SHIFT) & XFS_BLFT_MASK);
+}
+
+static inline __uint16_t
+xfs_blft_from_flags(struct xfs_buf_log_format *blf)
+{
+ return (blf->blf_flags & XFS_BLFT_MASK) >> XFS_BLFT_SHIFT;
+}
+
#endif /* __XFS_LOG_FORMAT_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 19/49] xfs: split out inode log item format definition
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (17 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 18/49] xfs: split out buf log item format definitions Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-04 23:41 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h Dave Chinner
` (30 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The EFI/EFD item format definitions are shared with userspace. Split
the out of header files that contain kernel only defintions to make
it simple to shared them.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 3 +-
include/libxlog.h | 1 -
include/xfs_extfree_item.h | 161 ---------------------------------------------
include/xfs_log_format.h | 83 +++++++++++++++++++++++
4 files changed, 85 insertions(+), 163 deletions(-)
delete mode 100644 include/xfs_extfree_item.h
diff --git a/include/Makefile b/include/Makefile
index f5c50b7..ad2ac46 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -27,7 +27,8 @@ QAHFILES = libxfs.h libxlog.h \
xfs_cksum.h \
xfs_da_btree.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
- xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \
+ xfs_ialloc.h \
+ xfs_ialloc_btree.h \
xfs_icreate_item.h \
xfs_inode.h \
xfs_inum.h \
diff --git a/include/libxlog.h b/include/libxlog.h
index 08f5dbb..ee23212 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -48,7 +48,6 @@ struct xlog {
};
#include <xfs/xfs_log_recover.h>
-#include <xfs/xfs_extfree_item.h>
#include <xfs/xfs_icreate_item.h>
/*
diff --git a/include/xfs_extfree_item.h b/include/xfs_extfree_item.h
deleted file mode 100644
index 375f68e..0000000
--- a/include/xfs_extfree_item.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_EXTFREE_ITEM_H__
-#define __XFS_EXTFREE_ITEM_H__
-
-struct xfs_mount;
-struct kmem_zone;
-
-typedef struct xfs_extent {
- xfs_dfsbno_t ext_start;
- xfs_extlen_t ext_len;
-} xfs_extent_t;
-
-/*
- * Since an xfs_extent_t has types (start:64, len: 32)
- * there are different alignments on 32 bit and 64 bit kernels.
- * So we provide the different variants for use by a
- * conversion routine.
- */
-
-typedef struct xfs_extent_32 {
- __uint64_t ext_start;
- __uint32_t ext_len;
-} __attribute__((packed)) xfs_extent_32_t;
-
-typedef struct xfs_extent_64 {
- __uint64_t ext_start;
- __uint32_t ext_len;
- __uint32_t ext_pad;
-} xfs_extent_64_t;
-
-/*
- * This is the structure used to lay out an efi log item in the
- * log. The efi_extents field is a variable size array whose
- * size is given by efi_nextents.
- */
-typedef struct xfs_efi_log_format {
- __uint16_t efi_type; /* efi log item type */
- __uint16_t efi_size; /* size of this item */
- __uint32_t efi_nextents; /* # extents to free */
- __uint64_t efi_id; /* efi identifier */
- xfs_extent_t efi_extents[1]; /* array of extents to free */
-} xfs_efi_log_format_t;
-
-typedef struct xfs_efi_log_format_32 {
- __uint16_t efi_type; /* efi log item type */
- __uint16_t efi_size; /* size of this item */
- __uint32_t efi_nextents; /* # extents to free */
- __uint64_t efi_id; /* efi identifier */
- xfs_extent_32_t efi_extents[1]; /* array of extents to free */
-} __attribute__((packed)) xfs_efi_log_format_32_t;
-
-typedef struct xfs_efi_log_format_64 {
- __uint16_t efi_type; /* efi log item type */
- __uint16_t efi_size; /* size of this item */
- __uint32_t efi_nextents; /* # extents to free */
- __uint64_t efi_id; /* efi identifier */
- xfs_extent_64_t efi_extents[1]; /* array of extents to free */
-} xfs_efi_log_format_64_t;
-
-/*
- * This is the structure used to lay out an efd log item in the
- * log. The efd_extents array is a variable size array whose
- * size is given by efd_nextents;
- */
-typedef struct xfs_efd_log_format {
- __uint16_t efd_type; /* efd log item type */
- __uint16_t efd_size; /* size of this item */
- __uint32_t efd_nextents; /* # of extents freed */
- __uint64_t efd_efi_id; /* id of corresponding efi */
- xfs_extent_t efd_extents[1]; /* array of extents freed */
-} xfs_efd_log_format_t;
-
-typedef struct xfs_efd_log_format_32 {
- __uint16_t efd_type; /* efd log item type */
- __uint16_t efd_size; /* size of this item */
- __uint32_t efd_nextents; /* # of extents freed */
- __uint64_t efd_efi_id; /* id of corresponding efi */
- xfs_extent_32_t efd_extents[1]; /* array of extents freed */
-} __attribute__((packed)) xfs_efd_log_format_32_t;
-
-typedef struct xfs_efd_log_format_64 {
- __uint16_t efd_type; /* efd log item type */
- __uint16_t efd_size; /* size of this item */
- __uint32_t efd_nextents; /* # of extents freed */
- __uint64_t efd_efi_id; /* id of corresponding efi */
- xfs_extent_64_t efd_extents[1]; /* array of extents freed */
-} xfs_efd_log_format_64_t;
-
-
-#ifdef __KERNEL__
-
-/*
- * Max number of extents in fast allocation path.
- */
-#define XFS_EFI_MAX_FAST_EXTENTS 16
-
-/*
- * Define EFI flag bits. Manipulated by set/clear/test_bit operators.
- */
-#define XFS_EFI_RECOVERED 1
-#define XFS_EFI_COMMITTED 2
-
-/*
- * This is the "extent free intention" log item. It is used
- * to log the fact that some extents need to be free. It is
- * used in conjunction with the "extent free done" log item
- * described below.
- */
-typedef struct xfs_efi_log_item {
- xfs_log_item_t efi_item;
- atomic_t efi_next_extent;
- unsigned long efi_flags; /* misc flags */
- xfs_efi_log_format_t efi_format;
-} xfs_efi_log_item_t;
-
-/*
- * This is the "extent free done" log item. It is used to log
- * the fact that some extents earlier mentioned in an efi item
- * have been freed.
- */
-typedef struct xfs_efd_log_item {
- xfs_log_item_t efd_item;
- xfs_efi_log_item_t *efd_efip;
- uint efd_next_extent;
- xfs_efd_log_format_t efd_format;
-} xfs_efd_log_item_t;
-
-/*
- * Max number of extents in fast allocation path.
- */
-#define XFS_EFD_MAX_FAST_EXTENTS 16
-
-extern struct kmem_zone *xfs_efi_zone;
-extern struct kmem_zone *xfs_efd_zone;
-
-xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
-xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
- uint);
-int xfs_efi_copy_format(xfs_log_iovec_t *buf,
- xfs_efi_log_format_t *dst_efi_fmt);
-void xfs_efi_item_free(xfs_efi_log_item_t *);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_EXTFREE_ITEM_H__ */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index 77a6024..d1e93d3 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -461,4 +461,87 @@ xfs_blft_from_flags(struct xfs_buf_log_format *blf)
return (blf->blf_flags & XFS_BLFT_MASK) >> XFS_BLFT_SHIFT;
}
+/*
+ * EFI/EFD log format definitions
+ */
+typedef struct xfs_extent {
+ xfs_dfsbno_t ext_start;
+ xfs_extlen_t ext_len;
+} xfs_extent_t;
+
+/*
+ * Since an xfs_extent_t has types (start:64, len: 32)
+ * there are different alignments on 32 bit and 64 bit kernels.
+ * So we provide the different variants for use by a
+ * conversion routine.
+ */
+typedef struct xfs_extent_32 {
+ __uint64_t ext_start;
+ __uint32_t ext_len;
+} __attribute__((packed)) xfs_extent_32_t;
+
+typedef struct xfs_extent_64 {
+ __uint64_t ext_start;
+ __uint32_t ext_len;
+ __uint32_t ext_pad;
+} xfs_extent_64_t;
+
+/*
+ * This is the structure used to lay out an efi log item in the
+ * log. The efi_extents field is a variable size array whose
+ * size is given by efi_nextents.
+ */
+typedef struct xfs_efi_log_format {
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
+ __uint64_t efi_id; /* efi identifier */
+ xfs_extent_t efi_extents[1]; /* array of extents to free */
+} xfs_efi_log_format_t;
+
+typedef struct xfs_efi_log_format_32 {
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
+ __uint64_t efi_id; /* efi identifier */
+ xfs_extent_32_t efi_extents[1]; /* array of extents to free */
+} __attribute__((packed)) xfs_efi_log_format_32_t;
+
+typedef struct xfs_efi_log_format_64 {
+ __uint16_t efi_type; /* efi log item type */
+ __uint16_t efi_size; /* size of this item */
+ __uint32_t efi_nextents; /* # extents to free */
+ __uint64_t efi_id; /* efi identifier */
+ xfs_extent_64_t efi_extents[1]; /* array of extents to free */
+} xfs_efi_log_format_64_t;
+
+/*
+ * This is the structure used to lay out an efd log item in the
+ * log. The efd_extents array is a variable size array whose
+ * size is given by efd_nextents;
+ */
+typedef struct xfs_efd_log_format {
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
+ __uint64_t efd_efi_id; /* id of corresponding efi */
+ xfs_extent_t efd_extents[1]; /* array of extents freed */
+} xfs_efd_log_format_t;
+
+typedef struct xfs_efd_log_format_32 {
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
+ __uint64_t efd_efi_id; /* id of corresponding efi */
+ xfs_extent_32_t efd_extents[1]; /* array of extents freed */
+} __attribute__((packed)) xfs_efd_log_format_32_t;
+
+typedef struct xfs_efd_log_format_64 {
+ __uint16_t efd_type; /* efd log item type */
+ __uint16_t efd_size; /* size of this item */
+ __uint32_t efd_nextents; /* # of extents freed */
+ __uint64_t efd_efi_id; /* id of corresponding efi */
+ xfs_extent_64_t efd_extents[1]; /* array of extents freed */
+} xfs_efd_log_format_64_t;
+
#endif /* __XFS_LOG_FORMAT_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (18 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 19/49] xfs: split out inode log item format definition Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-05 14:18 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h Dave Chinner
` (29 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The on disk format definitions of the on-disk dquot, log formats and
quota off log formats are all intertwined with other definitions for
quotas. Separate them out into their own header file so they can
easily be shared with userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 +
include/libxfs.h | 1 +
include/xfs_format.h | 86 +++++++++++++++++++++++++++++++++++
include/xfs_log_format.h | 58 ++++++++++++++++++++++++
include/xfs_quota.h | 114 -----------------------------------------------
include/xfs_types.h | 6 +++
6 files changed, 152 insertions(+), 114 deletions(-)
create mode 100644 include/xfs_format.h
diff --git a/include/Makefile b/include/Makefile
index ad2ac46..8f738a8 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -27,6 +27,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_cksum.h \
xfs_da_btree.h \
xfs_dinode.h xfs_dir2.h xfs_dir2_format.h \
+ xfs_format.h \
xfs_ialloc.h \
xfs_ialloc_btree.h \
xfs_icreate_item.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index 40e5e25..646ca79 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -37,6 +37,7 @@
#include <xfs/xfs_fs.h>
#include <xfs/xfs_arch.h>
+#include <xfs/xfs_format.h>
#include <xfs/xfs_log_format.h>
#include <xfs/xfs_bit.h>
diff --git a/include/xfs_format.h b/include/xfs_format.h
new file mode 100644
index 0000000..2b4f166
--- /dev/null
+++ b/include/xfs_format.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_FORMAT_H__
+#define __XFS_FORMAT_H__
+
+/*
+ * XFS On Disk Format Definitions
+ *
+ * This header file defines all the on-disk format definitions for
+ * general XFS objects. Directory and attribute related objects are defined in
+ * xfs_da_format.h, which log and log item formats are defined in
+ * xfs_log_format.h. Everything else goes here.
+ */
+
+/*
+ * Dquot and dquot block format definitions
+ */
+#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
+#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */
+
+/*
+ * This is the main portion of the on-disk representation of quota
+ * information for a user. This is the q_core of the xfs_dquot_t that
+ * is kept in kernel memory. We pad this with some more expansion room
+ * to construct the on disk structure.
+ */
+typedef struct xfs_disk_dquot {
+ __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
+ __u8 d_version; /* dquot version */
+ __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */
+ __be32 d_id; /* user,project,group id */
+ __be64 d_blk_hardlimit;/* absolute limit on disk blks */
+ __be64 d_blk_softlimit;/* preferred limit on disk blks */
+ __be64 d_ino_hardlimit;/* maximum # allocated inodes */
+ __be64 d_ino_softlimit;/* preferred inode limit */
+ __be64 d_bcount; /* disk blocks owned by the user */
+ __be64 d_icount; /* inodes owned by the user */
+ __be32 d_itimer; /* zero if within inode limits if not,
+ this is when we refuse service */
+ __be32 d_btimer; /* similar to above; for disk blocks */
+ __be16 d_iwarns; /* warnings issued wrt num inodes */
+ __be16 d_bwarns; /* warnings issued wrt disk blocks */
+ __be32 d_pad0; /* 64 bit align */
+ __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */
+ __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */
+ __be64 d_rtbcount; /* realtime blocks owned */
+ __be32 d_rtbtimer; /* similar to above; for RT disk blocks */
+ __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */
+ __be16 d_pad;
+} xfs_disk_dquot_t;
+
+/*
+ * This is what goes on disk. This is separated from the xfs_disk_dquot because
+ * carrying the unnecessary padding would be a waste of memory.
+ */
+typedef struct xfs_dqblk {
+ xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */
+ char dd_fill[4]; /* filling for posterity */
+
+ /*
+ * These two are only present on filesystems with the CRC bits set.
+ */
+ __be32 dd_crc; /* checksum */
+ __be64 dd_lsn; /* last modification in log */
+ uuid_t dd_uuid; /* location information */
+} xfs_dqblk_t;
+
+#define XFS_DQUOT_CRC_OFF offsetof(struct xfs_dqblk, dd_crc)
+
+
+#endif /* __XFS_FORMAT_H__ */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index d1e93d3..5963ec7 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -544,4 +544,62 @@ typedef struct xfs_efd_log_format_64 {
xfs_extent_64_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_64_t;
+/*
+ * Dquot Log format definitions.
+ *
+ * The first two fields must be the type and size fitting into
+ * 32 bits : log_recovery code assumes that.
+ */
+typedef struct xfs_dq_logformat {
+ __uint16_t qlf_type; /* dquot log item type */
+ __uint16_t qlf_size; /* size of this item */
+ xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
+ __int64_t qlf_blkno; /* blkno of dquot buffer */
+ __int32_t qlf_len; /* len of dquot buffer */
+ __uint32_t qlf_boffset; /* off of dquot in buffer */
+} xfs_dq_logformat_t;
+
+/*
+ * log format struct for QUOTAOFF records.
+ * The first two fields must be the type and size fitting into
+ * 32 bits : log_recovery code assumes that.
+ * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
+ * to the first and ensures that the first logitem is taken out of the AIL
+ * only when the last one is securely committed.
+ */
+typedef struct xfs_qoff_logformat {
+ unsigned short qf_type; /* quotaoff log item type */
+ unsigned short qf_size; /* size of this item */
+ unsigned int qf_flags; /* USR and/or GRP */
+ char qf_pad[12]; /* padding for future */
+} xfs_qoff_logformat_t;
+
+
+/*
+ * Disk quotas status in m_qflags, and also sb_qflags. 16 bits.
+ */
+#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
+#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
+#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
+#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
+#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
+#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
+#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
+
+/*
+ * Conversion to and from the combined OQUOTA flag (if necessary)
+ * is done only in xfs_sb_qflags_to_disk() and xfs_sb_qflags_from_disk()
+ */
+#define XFS_GQUOTA_ENFD 0x0080 /* group quota limits enforced */
+#define XFS_GQUOTA_CHKD 0x0100 /* quotacheck run on group quotas */
+#define XFS_PQUOTA_ENFD 0x0200 /* project quota limits enforced */
+#define XFS_PQUOTA_CHKD 0x0400 /* quotacheck run on project quotas */
+
+#define XFS_ALL_QUOTA_ACCT \
+ (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
+#define XFS_ALL_QUOTA_ENFD \
+ (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_ENFD)
+#define XFS_ALL_QUOTA_CHKD \
+ (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD)
+
#endif /* __XFS_LOG_FORMAT_H__ */
diff --git a/include/xfs_quota.h b/include/xfs_quota.h
index c61e31c..18dadf6 100644
--- a/include/xfs_quota.h
+++ b/include/xfs_quota.h
@@ -21,18 +21,6 @@
struct xfs_trans;
/*
- * The ondisk form of a dquot structure.
- */
-#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
-#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */
-
-/*
- * uid_t and gid_t are hard-coded to 32 bits in the inode.
- * Hence, an 'id' in a dquot is 32 bits..
- */
-typedef __uint32_t xfs_dqid_t;
-
-/*
* Even though users may not have quota limits occupying all 64-bits,
* they may need 64-bit accounting. Hence, 64-bit quota-counters,
* and quota-limits. This is a waste in the common case, but hey ...
@@ -41,53 +29,6 @@ typedef __uint64_t xfs_qcnt_t;
typedef __uint16_t xfs_qwarncnt_t;
/*
- * This is the main portion of the on-disk representation of quota
- * information for a user. This is the q_core of the xfs_dquot_t that
- * is kept in kernel memory. We pad this with some more expansion room
- * to construct the on disk structure.
- */
-typedef struct xfs_disk_dquot {
- __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
- __u8 d_version; /* dquot version */
- __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */
- __be32 d_id; /* user,project,group id */
- __be64 d_blk_hardlimit;/* absolute limit on disk blks */
- __be64 d_blk_softlimit;/* preferred limit on disk blks */
- __be64 d_ino_hardlimit;/* maximum # allocated inodes */
- __be64 d_ino_softlimit;/* preferred inode limit */
- __be64 d_bcount; /* disk blocks owned by the user */
- __be64 d_icount; /* inodes owned by the user */
- __be32 d_itimer; /* zero if within inode limits if not,
- this is when we refuse service */
- __be32 d_btimer; /* similar to above; for disk blocks */
- __be16 d_iwarns; /* warnings issued wrt num inodes */
- __be16 d_bwarns; /* warnings issued wrt disk blocks */
- __be32 d_pad0; /* 64 bit align */
- __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */
- __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */
- __be64 d_rtbcount; /* realtime blocks owned */
- __be32 d_rtbtimer; /* similar to above; for RT disk blocks */
- __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */
- __be16 d_pad;
-} xfs_disk_dquot_t;
-
-/*
- * This is what goes on disk. This is separated from the xfs_disk_dquot because
- * carrying the unnecessary padding would be a waste of memory.
- */
-typedef struct xfs_dqblk {
- xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */
- char dd_fill[4]; /* filling for posterity */
-
- /*
- * These two are only present on filesystems with the CRC bits set.
- */
- __be32 dd_crc; /* checksum */
- __be64 dd_lsn; /* last modification in log */
- uuid_t dd_uuid; /* location information */
-} xfs_dqblk_t;
-
-/*
* flags for q_flags field in the dquot.
*/
#define XFS_DQ_USER 0x0001 /* a user quota */
@@ -111,61 +52,6 @@ typedef struct xfs_dqblk {
*/
#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3)
-
-/*
- * These are the structures used to lay out dquots and quotaoff
- * records on the log. Quite similar to those of inodes.
- */
-
-/*
- * log format struct for dquots.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- */
-typedef struct xfs_dq_logformat {
- __uint16_t qlf_type; /* dquot log item type */
- __uint16_t qlf_size; /* size of this item */
- xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
- __int64_t qlf_blkno; /* blkno of dquot buffer */
- __int32_t qlf_len; /* len of dquot buffer */
- __uint32_t qlf_boffset; /* off of dquot in buffer */
-} xfs_dq_logformat_t;
-
-/*
- * log format struct for QUOTAOFF records.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
- * to the first and ensures that the first logitem is taken out of the AIL
- * only when the last one is securely committed.
- */
-typedef struct xfs_qoff_logformat {
- unsigned short qf_type; /* quotaoff log item type */
- unsigned short qf_size; /* size of this item */
- unsigned int qf_flags; /* USR and/or GRP */
- char qf_pad[12]; /* padding for future */
-} xfs_qoff_logformat_t;
-
-
-/*
- * Disk quotas status in m_qflags, and also sb_qflags. 16 bits.
- */
-#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
-#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
-#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
-#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
-#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
-#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
-#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
-
-/*
- * Quota Accounting/Enforcement flags
- */
-#define XFS_ALL_QUOTA_ACCT \
- (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
-#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
-#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
-
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
diff --git a/include/xfs_types.h b/include/xfs_types.h
index 543fdf0..b144a8f 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -178,4 +178,10 @@ struct xfs_name {
int len;
};
+/*
+ * uid_t and gid_t are hard-coded to 32 bits in the inode.
+ * Hence, an 'id' in a dquot is 32 bits..
+ */
+typedef __uint32_t xfs_dqid_t;
+
#endif /* __XFS_TYPES_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (19 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-05 14:27 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 22/49] xfs: split out on-disk transaction definitions Dave Chinner
` (28 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The on disk log format definitions for the icreate log item are
intertwined with the kernel-only in-memory log item definitions.
Separate the log format definitions out into their own header file
so they can easily be shared with userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 -
include/libxfs.h | 1 -
include/libxlog.h | 1 -
include/xfs_icreate_item.h | 55 ----------------------------------------------
include/xfs_log_format.h | 18 +++++++++++++++
5 files changed, 18 insertions(+), 58 deletions(-)
delete mode 100644 include/xfs_icreate_item.h
diff --git a/include/Makefile b/include/Makefile
index 8f738a8..ab71aad 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -30,7 +30,6 @@ QAHFILES = libxfs.h libxlog.h \
xfs_format.h \
xfs_ialloc.h \
xfs_ialloc_btree.h \
- xfs_icreate_item.h \
xfs_inode.h \
xfs_inum.h \
xfs_log_format.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index 646ca79..bc90082 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -59,7 +59,6 @@
#include <xfs/xfs_bmap.h>
#include <xfs/xfs_trace.h>
#include <xfs/xfs_symlink.h>
-#include <xfs/xfs_icreate_item.h>
#ifndef ARRAY_SIZE
diff --git a/include/libxlog.h b/include/libxlog.h
index ee23212..e65b607 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -48,7 +48,6 @@ struct xlog {
};
#include <xfs/xfs_log_recover.h>
-#include <xfs/xfs_icreate_item.h>
/*
* macros mapping kernel code to user code
diff --git a/include/xfs_icreate_item.h b/include/xfs_icreate_item.h
deleted file mode 100644
index 70dc03c..0000000
--- a/include/xfs_icreate_item.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2008-2010, Dave Chinner
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef XFS_ICREATE_ITEM_H
-#define XFS_ICREATE_ITEM_H 1
-
-/*
- * on disk log item structure
- *
- * Log recovery assumes the first two entries are the type and size and they fit
- * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so
- * decoding can be done correctly.
- */
-struct xfs_icreate_log {
- __uint16_t icl_type; /* type of log format structure */
- __uint16_t icl_size; /* size of log format structure */
- __be32 icl_ag; /* ag being allocated in */
- __be32 icl_agbno; /* start block of inode range */
- __be32 icl_count; /* number of inodes to initialise */
- __be32 icl_isize; /* size of inodes */
- __be32 icl_length; /* length of extent to initialise */
- __be32 icl_gen; /* inode generation number to use */
-};
-
-#ifdef __KERNEL__
-
-/* in memory log item structure */
-struct xfs_icreate_item {
- struct xfs_log_item ic_item;
- struct xfs_icreate_log ic_format;
-};
-
-extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
-
-void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno,
- xfs_agblock_t agbno, unsigned int count,
- unsigned int inode_size, xfs_agblock_t length,
- unsigned int generation);
-#endif /* __KERNEL__ */
-
-#endif /* XFS_ICREATE_ITEM_H */
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index 5963ec7..02639c7 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -602,4 +602,22 @@ typedef struct xfs_qoff_logformat {
#define XFS_ALL_QUOTA_CHKD \
(XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD)
+/*
+ * Inode create log item structure
+ *
+ * Log recovery assumes the first two entries are the type and size and they fit
+ * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so
+ * decoding can be done correctly.
+ */
+struct xfs_icreate_log {
+ __uint16_t icl_type; /* type of log format structure */
+ __uint16_t icl_size; /* size of log format structure */
+ __be32 icl_ag; /* ag being allocated in */
+ __be32 icl_agbno; /* start block of inode range */
+ __be32 icl_count; /* number of inodes to initialise */
+ __be32 icl_isize; /* size of inodes */
+ __be32 icl_length; /* length of extent to initialise */
+ __be32 icl_gen; /* inode generation number to use */
+};
+
#endif /* __XFS_LOG_FORMAT_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 22/49] xfs: split out on-disk transaction definitions
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (20 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-05 15:22 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h Dave Chinner
` (27 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There's a bunch of definitions in xfs_trans.h that define on-disk
formats - transaction headers taht get written into the log, log
item type definitions, etc. Split out everything into a separate
file so that all which remains in xfs_trans.h are kernel only
definitions.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_log_format.h | 141 +++++++++++++++++++++++++++++++++++++++++++++++
include/xfs_trans.h | 139 ----------------------------------------------
2 files changed, 141 insertions(+), 139 deletions(-)
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index 02639c7..bcd1c34 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -187,6 +187,147 @@ typedef struct xfs_log_iovec {
/*
+ * Transaction Header definitions.
+ *
+ * This is the structure written in the log at the head of every transaction. It
+ * identifies the type and id of the transaction, and contains the number of
+ * items logged by the transaction so we know how many to expect during
+ * recovery.
+ *
+ * Do not change the below structure without redoing the code in
+ * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans().
+ */
+typedef struct xfs_trans_header {
+ uint th_magic; /* magic number */
+ uint th_type; /* transaction type */
+ __int32_t th_tid; /* transaction id (unused) */
+ uint th_num_items; /* num items logged by trans */
+} xfs_trans_header_t;
+
+#define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */
+
+/*
+ * Log item types.
+ */
+#define XFS_LI_EFI 0x1236
+#define XFS_LI_EFD 0x1237
+#define XFS_LI_IUNLINK 0x1238
+#define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */
+#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
+#define XFS_LI_DQUOT 0x123d
+#define XFS_LI_QUOTAOFF 0x123e
+#define XFS_LI_ICREATE 0x123f
+
+#define XFS_LI_TYPE_DESC \
+ { XFS_LI_EFI, "XFS_LI_EFI" }, \
+ { XFS_LI_EFD, "XFS_LI_EFD" }, \
+ { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \
+ { XFS_LI_INODE, "XFS_LI_INODE" }, \
+ { XFS_LI_BUF, "XFS_LI_BUF" }, \
+ { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \
+ { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }, \
+ { XFS_LI_ICREATE, "XFS_LI_ICREATE" }
+
+/*
+ * Transaction types. Used to distinguish types of buffers.
+ */
+#define XFS_TRANS_SETATTR_NOT_SIZE 1
+#define XFS_TRANS_SETATTR_SIZE 2
+#define XFS_TRANS_INACTIVE 3
+#define XFS_TRANS_CREATE 4
+#define XFS_TRANS_CREATE_TRUNC 5
+#define XFS_TRANS_TRUNCATE_FILE 6
+#define XFS_TRANS_REMOVE 7
+#define XFS_TRANS_LINK 8
+#define XFS_TRANS_RENAME 9
+#define XFS_TRANS_MKDIR 10
+#define XFS_TRANS_RMDIR 11
+#define XFS_TRANS_SYMLINK 12
+#define XFS_TRANS_SET_DMATTRS 13
+#define XFS_TRANS_GROWFS 14
+#define XFS_TRANS_STRAT_WRITE 15
+#define XFS_TRANS_DIOSTRAT 16
+/* 17 was XFS_TRANS_WRITE_SYNC */
+#define XFS_TRANS_WRITEID 18
+#define XFS_TRANS_ADDAFORK 19
+#define XFS_TRANS_ATTRINVAL 20
+#define XFS_TRANS_ATRUNCATE 21
+#define XFS_TRANS_ATTR_SET 22
+#define XFS_TRANS_ATTR_RM 23
+#define XFS_TRANS_ATTR_FLAG 24
+#define XFS_TRANS_CLEAR_AGI_BUCKET 25
+#define XFS_TRANS_QM_SBCHANGE 26
+/*
+ * Dummy entries since we use the transaction type to index into the
+ * trans_type[] in xlog_recover_print_trans_head()
+ */
+#define XFS_TRANS_DUMMY1 27
+#define XFS_TRANS_DUMMY2 28
+#define XFS_TRANS_QM_QUOTAOFF 29
+#define XFS_TRANS_QM_DQALLOC 30
+#define XFS_TRANS_QM_SETQLIM 31
+#define XFS_TRANS_QM_DQCLUSTER 32
+#define XFS_TRANS_QM_QINOCREATE 33
+#define XFS_TRANS_QM_QUOTAOFF_END 34
+#define XFS_TRANS_SB_UNIT 35
+#define XFS_TRANS_FSYNC_TS 36
+#define XFS_TRANS_GROWFSRT_ALLOC 37
+#define XFS_TRANS_GROWFSRT_ZERO 38
+#define XFS_TRANS_GROWFSRT_FREE 39
+#define XFS_TRANS_SWAPEXT 40
+#define XFS_TRANS_SB_COUNT 41
+#define XFS_TRANS_CHECKPOINT 42
+#define XFS_TRANS_ICREATE 43
+#define XFS_TRANS_TYPE_MAX 43
+/* new transaction types need to be reflected in xfs_logprint(8) */
+
+#define XFS_TRANS_TYPES \
+ { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \
+ { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
+ { XFS_TRANS_INACTIVE, "INACTIVE" }, \
+ { XFS_TRANS_CREATE, "CREATE" }, \
+ { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
+ { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
+ { XFS_TRANS_REMOVE, "REMOVE" }, \
+ { XFS_TRANS_LINK, "LINK" }, \
+ { XFS_TRANS_RENAME, "RENAME" }, \
+ { XFS_TRANS_MKDIR, "MKDIR" }, \
+ { XFS_TRANS_RMDIR, "RMDIR" }, \
+ { XFS_TRANS_SYMLINK, "SYMLINK" }, \
+ { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \
+ { XFS_TRANS_GROWFS, "GROWFS" }, \
+ { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \
+ { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \
+ { XFS_TRANS_WRITEID, "WRITEID" }, \
+ { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \
+ { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \
+ { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \
+ { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \
+ { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \
+ { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \
+ { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \
+ { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \
+ { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \
+ { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \
+ { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \
+ { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \
+ { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \
+ { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \
+ { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \
+ { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \
+ { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \
+ { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \
+ { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \
+ { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \
+ { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \
+ { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \
+ { XFS_TRANS_DUMMY1, "DUMMY1" }, \
+ { XFS_TRANS_DUMMY2, "DUMMY2" }, \
+ { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" }
+
+
+
+/*
* Inode Log Item Format definitions.
*
* This is the structure used to lay out an inode log item in the
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index 36a0026..f92c2de 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -21,143 +21,6 @@
struct xfs_log_item;
/*
- * This is the structure written in the log at the head of
- * every transaction. It identifies the type and id of the
- * transaction, and contains the number of items logged by
- * the transaction so we know how many to expect during recovery.
- *
- * Do not change the below structure without redoing the code in
- * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans().
- */
-typedef struct xfs_trans_header {
- uint th_magic; /* magic number */
- uint th_type; /* transaction type */
- __int32_t th_tid; /* transaction id (unused) */
- uint th_num_items; /* num items logged by trans */
-} xfs_trans_header_t;
-
-#define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */
-
-/*
- * Log item types.
- */
-#define XFS_LI_EFI 0x1236
-#define XFS_LI_EFD 0x1237
-#define XFS_LI_IUNLINK 0x1238
-#define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */
-#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
-#define XFS_LI_DQUOT 0x123d
-#define XFS_LI_QUOTAOFF 0x123e
-#define XFS_LI_ICREATE 0x123f
-
-#define XFS_LI_TYPE_DESC \
- { XFS_LI_EFI, "XFS_LI_EFI" }, \
- { XFS_LI_EFD, "XFS_LI_EFD" }, \
- { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \
- { XFS_LI_INODE, "XFS_LI_INODE" }, \
- { XFS_LI_BUF, "XFS_LI_BUF" }, \
- { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \
- { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }, \
- { XFS_LI_ICREATE, "XFS_LI_ICREATE" }
-
-/*
- * Transaction types. Used to distinguish types of buffers.
- */
-#define XFS_TRANS_SETATTR_NOT_SIZE 1
-#define XFS_TRANS_SETATTR_SIZE 2
-#define XFS_TRANS_INACTIVE 3
-#define XFS_TRANS_CREATE 4
-#define XFS_TRANS_CREATE_TRUNC 5
-#define XFS_TRANS_TRUNCATE_FILE 6
-#define XFS_TRANS_REMOVE 7
-#define XFS_TRANS_LINK 8
-#define XFS_TRANS_RENAME 9
-#define XFS_TRANS_MKDIR 10
-#define XFS_TRANS_RMDIR 11
-#define XFS_TRANS_SYMLINK 12
-#define XFS_TRANS_SET_DMATTRS 13
-#define XFS_TRANS_GROWFS 14
-#define XFS_TRANS_STRAT_WRITE 15
-#define XFS_TRANS_DIOSTRAT 16
-/* 17 was XFS_TRANS_WRITE_SYNC */
-#define XFS_TRANS_WRITEID 18
-#define XFS_TRANS_ADDAFORK 19
-#define XFS_TRANS_ATTRINVAL 20
-#define XFS_TRANS_ATRUNCATE 21
-#define XFS_TRANS_ATTR_SET 22
-#define XFS_TRANS_ATTR_RM 23
-#define XFS_TRANS_ATTR_FLAG 24
-#define XFS_TRANS_CLEAR_AGI_BUCKET 25
-#define XFS_TRANS_QM_SBCHANGE 26
-/*
- * Dummy entries since we use the transaction type to index into the
- * trans_type[] in xlog_recover_print_trans_head()
- */
-#define XFS_TRANS_DUMMY1 27
-#define XFS_TRANS_DUMMY2 28
-#define XFS_TRANS_QM_QUOTAOFF 29
-#define XFS_TRANS_QM_DQALLOC 30
-#define XFS_TRANS_QM_SETQLIM 31
-#define XFS_TRANS_QM_DQCLUSTER 32
-#define XFS_TRANS_QM_QINOCREATE 33
-#define XFS_TRANS_QM_QUOTAOFF_END 34
-#define XFS_TRANS_SB_UNIT 35
-#define XFS_TRANS_FSYNC_TS 36
-#define XFS_TRANS_GROWFSRT_ALLOC 37
-#define XFS_TRANS_GROWFSRT_ZERO 38
-#define XFS_TRANS_GROWFSRT_FREE 39
-#define XFS_TRANS_SWAPEXT 40
-#define XFS_TRANS_SB_COUNT 41
-#define XFS_TRANS_CHECKPOINT 42
-#define XFS_TRANS_ICREATE 43
-#define XFS_TRANS_TYPE_MAX 43
-/* new transaction types need to be reflected in xfs_logprint(8) */
-
-#define XFS_TRANS_TYPES \
- { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \
- { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
- { XFS_TRANS_INACTIVE, "INACTIVE" }, \
- { XFS_TRANS_CREATE, "CREATE" }, \
- { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
- { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
- { XFS_TRANS_REMOVE, "REMOVE" }, \
- { XFS_TRANS_LINK, "LINK" }, \
- { XFS_TRANS_RENAME, "RENAME" }, \
- { XFS_TRANS_MKDIR, "MKDIR" }, \
- { XFS_TRANS_RMDIR, "RMDIR" }, \
- { XFS_TRANS_SYMLINK, "SYMLINK" }, \
- { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \
- { XFS_TRANS_GROWFS, "GROWFS" }, \
- { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \
- { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \
- { XFS_TRANS_WRITEID, "WRITEID" }, \
- { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \
- { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \
- { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \
- { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \
- { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \
- { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \
- { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \
- { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \
- { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \
- { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \
- { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \
- { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \
- { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \
- { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \
- { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \
- { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \
- { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \
- { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \
- { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \
- { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \
- { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \
- { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \
- { XFS_TRANS_DUMMY1, "DUMMY1" }, \
- { XFS_TRANS_DUMMY2, "DUMMY2" }, \
- { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" }
-
-/*
* This structure is used to track log items associated with
* a transaction. It points to the log item and keeps some
* flags to track the state of the log item. It also tracks
@@ -172,7 +35,6 @@ struct xfs_log_item_desc {
#define XFS_LID_DIRTY 0x1
-#define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */
/*
* Values for t_flags.
*/
@@ -209,7 +71,6 @@ struct xfs_log_item_desc {
#define XFS_TRANS_SB_REXTENTS 0x00001000
#define XFS_TRANS_SB_REXTSLOG 0x00002000
-
/*
* Per-extent log reservation for the allocation btree changes
* involved in freeing or allocating an extent.
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (21 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 22/49] xfs: split out on-disk transaction definitions Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-05 18:53 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 24/49] xfs: introduce xfs_quota_defs.h Dave Chinner
` (26 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There are quite a few realtime device definitions shared with
userspace. Move them from xfs_rtalloc.h to xfs_rt_alloc_defs.h
so we don't need to share xfs_rtalloc.h with userspace anymore.
This removes the final __KERNEL__ region from the XFS kernel
codebase. Yay!
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 5 +-
include/libxfs.h | 1 -
include/xfs_format.h | 41 +++++++++++++
include/xfs_rtalloc.h | 166 --------------------------------------------------
include/xfs_types.h | 10 +++
5 files changed, 55 insertions(+), 168 deletions(-)
delete mode 100644 include/xfs_rtalloc.h
diff --git a/include/Makefile b/include/Makefile
index ab71aad..3610726 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -35,7 +35,10 @@ QAHFILES = libxfs.h libxlog.h \
xfs_log_format.h \
xfs_log_recover.h \
xfs_metadump.h \
- xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h xfs_symlink.h \
+ xfs_mount.h \
+ xfs_quota.h \
+ xfs_sb.h \
+ xfs_symlink.h \
xfs_trace.h xfs_trans.h xfs_trans_space.h xfs_dfrag.h
HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h xfs_types.h
diff --git a/include/libxfs.h b/include/libxfs.h
index bc90082..8c09b77 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -614,7 +614,6 @@ extern int libxfs_nproc(void);
extern unsigned long libxfs_physmem(void); /* in kilobytes */
#include <xfs/xfs_ialloc.h>
-#include <xfs/xfs_rtalloc.h>
#include <xfs/xfs_attr_leaf.h>
#include <xfs/xfs_attr_remote.h>
diff --git a/include/xfs_format.h b/include/xfs_format.h
index 2b4f166..6205374 100644
--- a/include/xfs_format.h
+++ b/include/xfs_format.h
@@ -28,6 +28,47 @@
*/
/*
+ * RealTime Device format definitions
+ */
+
+/* Min and max rt extent sizes, specified in bytes */
+#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
+#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */
+#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */
+
+#define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize)
+#define XFS_BLOCKMASK(mp) ((mp)->m_blockmask)
+#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize)
+#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask)
+
+/*
+ * RT Summary and bit manipulation macros.
+ */
+#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb)))
+#define XFS_SUMOFFSTOBLOCK(mp,s) \
+ (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog)
+#define XFS_SUMPTR(mp,bp,so) \
+ ((xfs_suminfo_t *)((bp)->b_addr + \
+ (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp))))
+
+#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log)
+#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log)
+#define XFS_BITTOWORD(mp,bi) \
+ ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp)))
+
+#define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b))
+#define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b))
+
+#define XFS_RTLOBIT(w) xfs_lowbit32(w)
+#define XFS_RTHIBIT(w) xfs_highbit32(w)
+
+#if XFS_BIG_BLKNOS
+#define XFS_RTBLOCKLOG(b) xfs_highbit64(b)
+#else
+#define XFS_RTBLOCKLOG(b) xfs_highbit32(b)
+#endif
+
+/*
* Dquot and dquot block format definitions
*/
#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
diff --git a/include/xfs_rtalloc.h b/include/xfs_rtalloc.h
deleted file mode 100644
index f7f3a35..0000000
--- a/include/xfs_rtalloc.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_RTALLOC_H__
-#define __XFS_RTALLOC_H__
-
-struct xfs_mount;
-struct xfs_trans;
-
-/* Min and max rt extent sizes, specified in bytes */
-#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
-#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */
-#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */
-
-/*
- * Constants for bit manipulations.
- */
-#define XFS_NBBYLOG 3 /* log2(NBBY) */
-#define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */
-#define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG)
-#define XFS_NBWORD (1 << XFS_NBWORDLOG)
-#define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1)
-
-#define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize)
-#define XFS_BLOCKMASK(mp) ((mp)->m_blockmask)
-#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize)
-#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask)
-
-/*
- * Summary and bit manipulation macros.
- */
-#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb)))
-#define XFS_SUMOFFSTOBLOCK(mp,s) \
- (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog)
-#define XFS_SUMPTR(mp,bp,so) \
- ((xfs_suminfo_t *)((bp)->b_addr + \
- (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp))))
-
-#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log)
-#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log)
-#define XFS_BITTOWORD(mp,bi) \
- ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp)))
-
-#define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b))
-#define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b))
-
-#define XFS_RTLOBIT(w) xfs_lowbit32(w)
-#define XFS_RTHIBIT(w) xfs_highbit32(w)
-
-#if XFS_BIG_BLKNOS
-#define XFS_RTBLOCKLOG(b) xfs_highbit64(b)
-#else
-#define XFS_RTBLOCKLOG(b) xfs_highbit32(b)
-#endif
-
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_XFS_RT
-/*
- * Function prototypes for exported functions.
- */
-
-/*
- * Allocate an extent in the realtime subvolume, with the usual allocation
- * parameters. The length units are all in realtime extents, as is the
- * result block number.
- */
-int /* error */
-xfs_rtallocate_extent(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to allocate */
- xfs_extlen_t minlen, /* minimum length to allocate */
- xfs_extlen_t maxlen, /* maximum length to allocate */
- xfs_extlen_t *len, /* out: actual length allocated */
- xfs_alloctype_t type, /* allocation type XFS_ALLOCTYPE... */
- int wasdel, /* was a delayed allocation extent */
- xfs_extlen_t prod, /* extent product factor */
- xfs_rtblock_t *rtblock); /* out: start block allocated */
-
-/*
- * Free an extent in the realtime subvolume. Length is expressed in
- * realtime extents, as is the block number.
- */
-int /* error */
-xfs_rtfree_extent(
- struct xfs_trans *tp, /* transaction pointer */
- xfs_rtblock_t bno, /* starting block number to free */
- xfs_extlen_t len); /* length of extent freed */
-
-/*
- * Initialize realtime fields in the mount structure.
- */
-int /* error */
-xfs_rtmount_init(
- struct xfs_mount *mp); /* file system mount structure */
-void
-xfs_rtunmount_inodes(
- struct xfs_mount *mp);
-
-/*
- * Get the bitmap and summary inodes into the mount structure
- * at mount time.
- */
-int /* error */
-xfs_rtmount_inodes(
- struct xfs_mount *mp); /* file system mount structure */
-
-/*
- * Pick an extent for allocation at the start of a new realtime file.
- * Use the sequence number stored in the atime field of the bitmap inode.
- * Translate this to a fraction of the rtextents, and return the product
- * of rtextents and the fraction.
- * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
- */
-int /* error */
-xfs_rtpick_extent(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_extlen_t len, /* allocation length (rtextents) */
- xfs_rtblock_t *pick); /* result rt extent */
-
-/*
- * Grow the realtime area of the filesystem.
- */
-int
-xfs_growfs_rt(
- struct xfs_mount *mp, /* file system mount structure */
- xfs_growfs_rt_t *in); /* user supplied growfs struct */
-
-#else
-# define xfs_rtallocate_extent(t,b,min,max,l,a,f,p,rb) (ENOSYS)
-# define xfs_rtfree_extent(t,b,l) (ENOSYS)
-# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS)
-# define xfs_growfs_rt(mp,in) (ENOSYS)
-static inline int /* error */
-xfs_rtmount_init(
- xfs_mount_t *mp) /* file system mount structure */
-{
- if (mp->m_sb.sb_rblocks == 0)
- return 0;
-
- xfs_warn(mp, "Not built with CONFIG_XFS_RT");
- return ENOSYS;
-}
-# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
-# define xfs_rtunmount_inodes(m)
-#endif /* CONFIG_XFS_RT */
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_RTALLOC_H__ */
diff --git a/include/xfs_types.h b/include/xfs_types.h
index b144a8f..6ed6b26 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -184,4 +184,14 @@ struct xfs_name {
*/
typedef __uint32_t xfs_dqid_t;
+/*
+ * Constants for bit manipulations.
+ */
+#define XFS_NBBYLOG 3 /* log2(NBBY) */
+#define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */
+#define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG)
+#define XFS_NBWORD (1 << XFS_NBWORDLOG)
+#define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1)
+
+
#endif /* __XFS_TYPES_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 24/49] xfs: introduce xfs_quota_defs.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (22 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h Dave Chinner
@ 2013-07-19 6:44 ` Dave Chinner
2013-08-05 19:09 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 25/49] libxfs: introduce xfs_trans_resv.c Dave Chinner
` (25 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:44 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There are a lot of quota flag definitions that are shared by user
and kernel space. Move them all to xfs_quota_defs.h so we can
unshare xfs_quota.h and remove the __KERNEL__ regions from it.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 2 +-
include/libxfs.h | 2 +-
include/xfs_quota.h | 279 -----------------------------------------------
include/xfs_quota_defs.h | 157 ++++++++++++++++++++++++++
4 files changed, 159 insertions(+), 281 deletions(-)
delete mode 100644 include/xfs_quota.h
create mode 100644 include/xfs_quota_defs.h
diff --git a/include/Makefile b/include/Makefile
index 3610726..11f13dd 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -36,7 +36,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_log_recover.h \
xfs_metadump.h \
xfs_mount.h \
- xfs_quota.h \
+ xfs_quota_defs.h \
xfs_sb.h \
xfs_symlink.h \
xfs_trace.h xfs_trans.h xfs_trans_space.h xfs_dfrag.h
diff --git a/include/libxfs.h b/include/libxfs.h
index 8c09b77..81495c3 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -39,6 +39,7 @@
#include <xfs/xfs_format.h>
#include <xfs/xfs_log_format.h>
+#include <xfs/xfs_quota_defs.h>
#include <xfs/xfs_bit.h>
#include <xfs/xfs_inum.h>
@@ -617,7 +618,6 @@ extern unsigned long libxfs_physmem(void); /* in kilobytes */
#include <xfs/xfs_attr_leaf.h>
#include <xfs/xfs_attr_remote.h>
-#include <xfs/xfs_quota.h>
#include <xfs/xfs_trans_space.h>
#define XFS_INOBT_IS_FREE_DISK(rp,i) \
diff --git a/include/xfs_quota.h b/include/xfs_quota.h
deleted file mode 100644
index 18dadf6..0000000
--- a/include/xfs_quota.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_QUOTA_H__
-#define __XFS_QUOTA_H__
-
-struct xfs_trans;
-
-/*
- * Even though users may not have quota limits occupying all 64-bits,
- * they may need 64-bit accounting. Hence, 64-bit quota-counters,
- * and quota-limits. This is a waste in the common case, but hey ...
- */
-typedef __uint64_t xfs_qcnt_t;
-typedef __uint16_t xfs_qwarncnt_t;
-
-/*
- * flags for q_flags field in the dquot.
- */
-#define XFS_DQ_USER 0x0001 /* a user quota */
-#define XFS_DQ_PROJ 0x0002 /* project quota */
-#define XFS_DQ_GROUP 0x0004 /* a group quota */
-#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */
-#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */
-
-#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
-
-#define XFS_DQ_FLAGS \
- { XFS_DQ_USER, "USER" }, \
- { XFS_DQ_PROJ, "PROJ" }, \
- { XFS_DQ_GROUP, "GROUP" }, \
- { XFS_DQ_DIRTY, "DIRTY" }, \
- { XFS_DQ_FREEING, "FREEING" }
-
-/*
- * In the worst case, when both user and group quotas are on,
- * we can have a max of three dquots changing in a single transaction.
- */
-#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3)
-
-#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
-#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
-#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
-#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
-#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
-#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD)
-
-/*
- * Incore only flags for quotaoff - these bits get cleared when quota(s)
- * are in the process of getting turned off. These flags are in m_qflags but
- * never in sb_qflags.
- */
-#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
-#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
-#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
-#define XFS_ALL_QUOTA_ACTIVE \
- (XFS_UQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
-
-/*
- * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
- * quota will be not be switched off as long as that inode lock is held.
- */
-#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
- XFS_GQUOTA_ACTIVE | \
- XFS_PQUOTA_ACTIVE))
-#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
- XFS_PQUOTA_ACTIVE))
-#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
-#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
-#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
-
-/*
- * Flags to tell various functions what to do. Not all of these are meaningful
- * to a single function. None of these XFS_QMOPT_* flags are meant to have
- * persistent values (ie. their values can and will change between versions)
- */
-#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
-#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
-#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
-#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
-#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
-#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
-#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
-#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
-#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
-
-/*
- * flags to xfs_trans_mod_dquot to indicate which field needs to be
- * modified.
- */
-#define XFS_QMOPT_RES_REGBLKS 0x0010000
-#define XFS_QMOPT_RES_RTBLKS 0x0020000
-#define XFS_QMOPT_BCOUNT 0x0040000
-#define XFS_QMOPT_ICOUNT 0x0080000
-#define XFS_QMOPT_RTBCOUNT 0x0100000
-#define XFS_QMOPT_DELBCOUNT 0x0200000
-#define XFS_QMOPT_DELRTBCOUNT 0x0400000
-#define XFS_QMOPT_RES_INOS 0x0800000
-
-/*
- * flags for dqalloc.
- */
-#define XFS_QMOPT_INHERIT 0x1000000
-
-/*
- * flags to xfs_trans_mod_dquot.
- */
-#define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS
-#define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS
-#define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS
-#define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT
-#define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT
-#define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT
-#define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT
-#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
-
-
-#define XFS_QMOPT_QUOTALL \
- (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
-#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
-
-#ifdef __KERNEL__
-/*
- * This check is done typically without holding the inode lock;
- * that may seem racy, but it is harmless in the context that it is used.
- * The inode cannot go inactive as long a reference is kept, and
- * therefore if dquot(s) were attached, they'll stay consistent.
- * If, for example, the ownership of the inode changes while
- * we didn't have the inode locked, the appropriate dquot(s) will be
- * attached atomically.
- */
-#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
- (ip)->i_udquot == NULL) || \
- (XFS_IS_OQUOTA_ON(mp) && \
- (ip)->i_gdquot == NULL))
-
-#define XFS_QM_NEED_QUOTACHECK(mp) \
- ((XFS_IS_UQUOTA_ON(mp) && \
- (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
- (XFS_IS_GQUOTA_ON(mp) && \
- ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
- (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
- (XFS_IS_PQUOTA_ON(mp) && \
- ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
- (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
-
-#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
-
-#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
-
-#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
- XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
- XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
- XFS_GQUOTA_ACCT)
-
-
-/*
- * The structure kept inside the xfs_trans_t keep track of dquot changes
- * within a transaction and apply them later.
- */
-typedef struct xfs_dqtrx {
- struct xfs_dquot *qt_dquot; /* the dquot this refers to */
- ulong qt_blk_res; /* blks reserved on a dquot */
- ulong qt_blk_res_used; /* blks used from the reservation */
- ulong qt_ino_res; /* inode reserved on a dquot */
- ulong qt_ino_res_used; /* inodes used from the reservation */
- long qt_bcount_delta; /* dquot blk count changes */
- long qt_delbcnt_delta; /* delayed dquot blk count changes */
- long qt_icount_delta; /* dquot inode count changes */
- ulong qt_rtblk_res; /* # blks reserved on a dquot */
- ulong qt_rtblk_res_used;/* # blks used from reservation */
- long qt_rtbcount_delta;/* dquot realtime blk changes */
- long qt_delrtb_delta; /* delayed RT blk count changes */
-} xfs_dqtrx_t;
-
-#ifdef CONFIG_XFS_QUOTA
-extern void xfs_trans_dup_dqinfo(struct xfs_trans *, struct xfs_trans *);
-extern void xfs_trans_free_dqinfo(struct xfs_trans *);
-extern void xfs_trans_mod_dquot_byino(struct xfs_trans *, struct xfs_inode *,
- uint, long);
-extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *);
-extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *);
-extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *,
- struct xfs_inode *, long, long, uint);
-extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
- struct xfs_mount *, struct xfs_dquot *,
- struct xfs_dquot *, long, long, uint);
-
-extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint,
- struct xfs_dquot **, struct xfs_dquot **);
-extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *,
- struct xfs_dquot *, struct xfs_dquot *);
-extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **);
-extern struct xfs_dquot *xfs_qm_vop_chown(struct xfs_trans *,
- struct xfs_inode *, struct xfs_dquot **, struct xfs_dquot *);
-extern int xfs_qm_vop_chown_reserve(struct xfs_trans *, struct xfs_inode *,
- struct xfs_dquot *, struct xfs_dquot *, uint);
-extern int xfs_qm_dqattach(struct xfs_inode *, uint);
-extern int xfs_qm_dqattach_locked(struct xfs_inode *, uint);
-extern void xfs_qm_dqdetach(struct xfs_inode *);
-extern void xfs_qm_dqrele(struct xfs_dquot *);
-extern void xfs_qm_statvfs(struct xfs_inode *, struct kstatfs *);
-extern int xfs_qm_newmount(struct xfs_mount *, uint *, uint *);
-extern void xfs_qm_mount_quotas(struct xfs_mount *);
-extern void xfs_qm_unmount(struct xfs_mount *);
-extern void xfs_qm_unmount_quotas(struct xfs_mount *);
-
-#else
-static inline int
-xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
- uint flags, struct xfs_dquot **udqp, struct xfs_dquot **gdqp)
-{
- *udqp = NULL;
- *gdqp = NULL;
- return 0;
-}
-#define xfs_trans_dup_dqinfo(tp, tp2)
-#define xfs_trans_free_dqinfo(tp)
-#define xfs_trans_mod_dquot_byino(tp, ip, fields, delta)
-#define xfs_trans_apply_dquot_deltas(tp)
-#define xfs_trans_unreserve_and_mod_dquots(tp)
-static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp,
- struct xfs_inode *ip, long nblks, long ninos, uint flags)
-{
- return 0;
-}
-static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
- struct xfs_mount *mp, struct xfs_dquot *udqp,
- struct xfs_dquot *gdqp, long nblks, long nions, uint flags)
-{
- return 0;
-}
-#define xfs_qm_vop_create_dqattach(tp, ip, u, g)
-#define xfs_qm_vop_rename_dqattach(it) (0)
-#define xfs_qm_vop_chown(tp, ip, old, new) (NULL)
-#define xfs_qm_vop_chown_reserve(tp, ip, u, g, fl) (0)
-#define xfs_qm_dqattach(ip, fl) (0)
-#define xfs_qm_dqattach_locked(ip, fl) (0)
-#define xfs_qm_dqdetach(ip)
-#define xfs_qm_dqrele(d)
-#define xfs_qm_statvfs(ip, s)
-#define xfs_qm_newmount(mp, a, b) (0)
-#define xfs_qm_mount_quotas(mp)
-#define xfs_qm_unmount(mp)
-#define xfs_qm_unmount_quotas(mp)
-#endif /* CONFIG_XFS_QUOTA */
-
-#define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \
- xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), -(ninos), flags)
-#define xfs_trans_reserve_quota(tp, mp, ud, gd, nb, ni, f) \
- xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, nb, ni, \
- f | XFS_QMOPT_RES_REGBLKS)
-
-extern int xfs_qm_dqcheck(struct xfs_mount *, xfs_disk_dquot_t *,
- xfs_dqid_t, uint, uint, char *);
-extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
-
-extern const struct xfs_buf_ops xfs_dquot_buf_ops;
-
-#endif /* __KERNEL__ */
-#endif /* __XFS_QUOTA_H__ */
diff --git a/include/xfs_quota_defs.h b/include/xfs_quota_defs.h
new file mode 100644
index 0000000..e6b0d6e
--- /dev/null
+++ b/include/xfs_quota_defs.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_QUOTA_DEFS_H__
+#define __XFS_QUOTA_DEFS_H__
+
+/*
+ * Quota definitions shared between user and kernel source trees.
+ */
+
+/*
+ * Even though users may not have quota limits occupying all 64-bits,
+ * they may need 64-bit accounting. Hence, 64-bit quota-counters,
+ * and quota-limits. This is a waste in the common case, but hey ...
+ */
+typedef __uint64_t xfs_qcnt_t;
+typedef __uint16_t xfs_qwarncnt_t;
+
+/*
+ * flags for q_flags field in the dquot.
+ */
+#define XFS_DQ_USER 0x0001 /* a user quota */
+#define XFS_DQ_PROJ 0x0002 /* project quota */
+#define XFS_DQ_GROUP 0x0004 /* a group quota */
+#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */
+#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */
+
+#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
+
+#define XFS_DQ_FLAGS \
+ { XFS_DQ_USER, "USER" }, \
+ { XFS_DQ_PROJ, "PROJ" }, \
+ { XFS_DQ_GROUP, "GROUP" }, \
+ { XFS_DQ_DIRTY, "DIRTY" }, \
+ { XFS_DQ_FREEING, "FREEING" }
+
+/*
+ * We have the possibility of all three quota types being active at once, and
+ * hence free space modification requires modification of all three current
+ * dquots in a single transaction. For this case we need to have a reservation
+ * of at least 3 dquots.
+ *
+ * However, a chmod operation can change both UID and GID in a single
+ * transaction, resulting in requiring {old, new} x {uid, gid} dquots to be
+ * modified. Hence for this case we need to reserve space for at least 4 dquots.
+ *
+ * And in the worst case, there's a rename operation that can be modifying up to
+ * 4 inodes with dquots attached to them. In reality, the only inodes that can
+ * have their dquots modified are the source and destination directory inodes
+ * due to directory name creation and removal. That can require space allocation
+ * and/or freeing on both directory inodes, and hence all three dquots on each
+ * inode can be modified. And if the directories are world writeable, all the
+ * dquots can be unique and so 6 dquots can be modified....
+ *
+ * And, of course, we also need to take into account the dquot log format item
+ * used to describe each dquot.
+ */
+#define XFS_DQUOT_LOGRES(mp) \
+ ((sizeof(struct xfs_dq_logformat) + sizeof(struct xfs_disk_dquot)) * 6)
+
+#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
+#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
+#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
+#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
+#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
+#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD)
+#define XFS_IS_PQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_PQUOTA_ENFD)
+
+/*
+ * Incore only flags for quotaoff - these bits get cleared when quota(s)
+ * are in the process of getting turned off. These flags are in m_qflags but
+ * never in sb_qflags.
+ */
+#define XFS_UQUOTA_ACTIVE 0x1000 /* uquotas are being turned off */
+#define XFS_GQUOTA_ACTIVE 0x2000 /* gquotas are being turned off */
+#define XFS_PQUOTA_ACTIVE 0x4000 /* pquotas are being turned off */
+#define XFS_ALL_QUOTA_ACTIVE \
+ (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
+
+/*
+ * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
+ * quota will be not be switched off as long as that inode lock is held.
+ */
+#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
+ XFS_GQUOTA_ACTIVE | \
+ XFS_PQUOTA_ACTIVE))
+#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
+ XFS_PQUOTA_ACTIVE))
+#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
+#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
+#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
+
+/*
+ * Flags to tell various functions what to do. Not all of these are meaningful
+ * to a single function. None of these XFS_QMOPT_* flags are meant to have
+ * persistent values (ie. their values can and will change between versions)
+ */
+#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
+#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
+#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
+#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
+#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
+#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
+#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
+#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
+#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
+
+/*
+ * flags to xfs_trans_mod_dquot to indicate which field needs to be
+ * modified.
+ */
+#define XFS_QMOPT_RES_REGBLKS 0x0010000
+#define XFS_QMOPT_RES_RTBLKS 0x0020000
+#define XFS_QMOPT_BCOUNT 0x0040000
+#define XFS_QMOPT_ICOUNT 0x0080000
+#define XFS_QMOPT_RTBCOUNT 0x0100000
+#define XFS_QMOPT_DELBCOUNT 0x0200000
+#define XFS_QMOPT_DELRTBCOUNT 0x0400000
+#define XFS_QMOPT_RES_INOS 0x0800000
+
+/*
+ * flags for dqalloc.
+ */
+#define XFS_QMOPT_INHERIT 0x1000000
+
+/*
+ * flags to xfs_trans_mod_dquot.
+ */
+#define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS
+#define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS
+#define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS
+#define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT
+#define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT
+#define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT
+#define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT
+#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
+
+
+#define XFS_QMOPT_QUOTALL \
+ (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
+#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
+
+#endif /* __XFS_QUOTA_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 25/49] libxfs: introduce xfs_trans_resv.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (23 preceding siblings ...)
2013-07-19 6:44 ` [PATCH 24/49] xfs: introduce xfs_quota_defs.h Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-05 20:16 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 26/49] libxfs: move transaction code to trans.c Dave Chinner
` (24 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The log space reservation calculation code has been separated from
the core transaction code in kernelspace. THi smeans we can add it
here in preparation for removing xfs_trans.c to further reduce the
differences between kernel and usrspace files.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 6 +-
include/libxfs.h | 20 +-
include/xfs_mount.h | 33 +--
include/xfs_trans.h | 75 +-----
include/xfs_trans_resv.h | 137 ++++++++++
libxfs/Makefile | 7 +-
libxfs/xfs.h | 2 +
libxfs/xfs_trans.c | 576 +---------------------------------------
libxfs/xfs_trans_resv.c | 677 +++++++++++++++++++++++++++++++++++++++++++++++
mkfs/maxtrres.c | 8 +-
10 files changed, 852 insertions(+), 689 deletions(-)
create mode 100644 include/xfs_trans_resv.h
create mode 100644 libxfs/xfs_trans_resv.c
diff --git a/include/Makefile b/include/Makefile
index 11f13dd..3d1ba0a 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -39,7 +39,11 @@ QAHFILES = libxfs.h libxlog.h \
xfs_quota_defs.h \
xfs_sb.h \
xfs_symlink.h \
- xfs_trace.h xfs_trans.h xfs_trans_space.h xfs_dfrag.h
+ xfs_trace.h \
+ xfs_trans.h \
+ xfs_trans_resv.h \
+ xfs_trans_space.h \
+ xfs_dfrag.h
HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h xfs_types.h
HFILES += $(PKG_PLATFORM).h
diff --git a/include/libxfs.h b/include/libxfs.h
index 81495c3..181fe3c 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -40,6 +40,7 @@
#include <xfs/xfs_format.h>
#include <xfs/xfs_log_format.h>
#include <xfs/xfs_quota_defs.h>
+#include <xfs/xfs_trans_resv.h>
#include <xfs/xfs_bit.h>
#include <xfs/xfs_inum.h>
@@ -204,7 +205,7 @@ typedef struct xfs_mount {
int m_ialloc_blks; /* blocks in inode allocation */
int m_litino; /* size of inode union area */
int m_inoalign_mask;/* mask sb_inoalignmt if used */
- xfs_trans_reservations_t m_reservations;/* precomputed res values */
+ struct xfs_trans_resv m_reservations; /* precomputed res values */
__uint64_t m_maxicount; /* maximum inode count */
int m_dalign; /* stripe unit */
int m_swidth; /* stripe width */
@@ -408,7 +409,6 @@ extern int libxfs_ihash_size;
extern void libxfs_iomove (xfs_buf_t *, uint, int, void *, int);
-
/*
* Transaction interface
*/
@@ -445,6 +445,19 @@ typedef struct xfs_buf_log_item {
#include <xfs/xfs_trans.h>
+typedef struct xfs_dq_logitem {
+ xfs_log_item_t qli_item; /* common portion */
+ struct xfs_dquot *qli_dquot; /* dquot ptr */
+ xfs_lsn_t qli_flush_lsn; /* lsn at last flush */
+ xfs_dq_logformat_t qli_format; /* logged structure */
+} xfs_dq_logitem_t;
+
+typedef struct xfs_qoff_logitem {
+ xfs_log_item_t qql_item; /* common portion */
+ struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */
+ xfs_qoff_logformat_t qql_format; /* logged structure */
+} xfs_qoff_logitem_t;
+
typedef struct xfs_trans {
unsigned int t_type; /* transaction type */
unsigned int t_log_res; /* amt of log space resvd */
@@ -700,6 +713,9 @@ void xfs_dinode_from_disk(struct xfs_icdinode *,
#define libxfs_symlink_blocks xfs_symlink_blocks
#define libxfs_symlink_hdr_ok xfs_symlink_hdr_ok
+/* xfs_trans_resv.h */
+#define libxfs_trans_resv_calc xfs_trans_resv_calc
+
/* xfs_rtalloc.c */
int libxfs_rtfree_extent(struct xfs_trans *, xfs_rtblock_t, xfs_extlen_t);
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 68c02a9..5410e9f 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -18,37 +18,6 @@
#ifndef __XFS_MOUNT_H__
#define __XFS_MOUNT_H__
-typedef struct xfs_trans_reservations {
- uint tr_write; /* extent alloc trans */
- uint tr_itruncate; /* truncate trans */
- uint tr_rename; /* rename trans */
- uint tr_link; /* link trans */
- uint tr_remove; /* unlink trans */
- uint tr_symlink; /* symlink trans */
- uint tr_create; /* create trans */
- uint tr_mkdir; /* mkdir trans */
- uint tr_ifree; /* inode free trans */
- uint tr_ichange; /* inode update trans */
- uint tr_growdata; /* fs data section grow trans */
- uint tr_swrite; /* sync write inode trans */
- uint tr_addafork; /* cvt inode to attributed trans */
- uint tr_writeid; /* write setuid/setgid file */
- uint tr_attrinval; /* attr fork buffer invalidation */
- uint tr_attrsetm; /* set/create an attribute at mount time */
- uint tr_attrsetrt; /* set/create an attribute at runtime */
- uint tr_attrrm; /* remove an attribute */
- uint tr_clearagi; /* clear bad agi unlinked ino bucket */
- uint tr_growrtalloc; /* grow realtime allocations */
- uint tr_growrtzero; /* grow realtime zeroing */
- uint tr_growrtfree; /* grow realtime freeing */
- uint tr_qm_sbchange; /* change quota flags */
- uint tr_qm_setqlim; /* adjust quota limits */
- uint tr_qm_dqalloc; /* allocate quota on disk */
- uint tr_qm_quotaoff; /* turn quota off */
- uint tr_qm_equotaoff;/* end of turn quota off */
- uint tr_sb; /* modify superblock */
-} xfs_trans_reservations_t;
-
#ifndef __KERNEL__
#define xfs_daddr_to_agno(mp,d) \
@@ -174,7 +143,7 @@ typedef struct xfs_mount {
int m_ialloc_blks; /* blocks in inode allocation */
int m_inoalign_mask;/* mask sb_inoalignmt if used */
uint m_qflags; /* quota status flags */
- xfs_trans_reservations_t m_reservations;/* precomputed res values */
+ struct xfs_trans_resv m_reservations; /* precomputed res values */
__uint64_t m_maxicount; /* maximum inode count */
__uint64_t m_resblks; /* total reserved blocks */
__uint64_t m_resblks_avail;/* available reserved blocks */
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index f92c2de..e504103 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -20,6 +20,8 @@
struct xfs_log_item;
+#include "xfs_trans_resv.h"
+
/*
* This structure is used to track log items associated with
* a transaction. It points to the log item and keeps some
@@ -72,79 +74,6 @@ struct xfs_log_item_desc {
#define XFS_TRANS_SB_REXTSLOG 0x00002000
/*
- * Per-extent log reservation for the allocation btree changes
- * involved in freeing or allocating an extent.
- * 2 trees * (2 blocks/level * max depth - 1) * block size
- */
-#define XFS_ALLOCFREE_LOG_RES(mp,nx) \
- ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1)))
-#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
- ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1)))
-
-/*
- * Per-directory log reservation for any directory change.
- * dir blocks: (1 btree block per level + data block + free block) * dblock size
- * bmap btree: (levels + 2) * max depth * block size
- * v2 directory blocks can be fragmented below the dirblksize down to the fsb
- * size, so account for that in the DAENTER macros.
- */
-#define XFS_DIROP_LOG_RES(mp) \
- (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
- (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
-#define XFS_DIROP_LOG_COUNT(mp) \
- (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
- XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
-
-
-#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
-#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
-#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
-#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
-#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
-#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
-#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
-#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
-#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
-#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
-#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
-#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
-#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
-#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
-#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-/*
- * Logging the inode timestamps on an fsync -- same as SWRITE
- * as long as SWRITE logs the entire inode core
- */
-#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
-#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
-#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm)
-#define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt)
-#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
-#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
-
-
-/*
- * Various log count values.
- */
-#define XFS_DEFAULT_LOG_COUNT 1
-#define XFS_DEFAULT_PERM_LOG_COUNT 2
-#define XFS_ITRUNCATE_LOG_COUNT 2
-#define XFS_INACTIVE_LOG_COUNT 2
-#define XFS_CREATE_LOG_COUNT 2
-#define XFS_MKDIR_LOG_COUNT 3
-#define XFS_SYMLINK_LOG_COUNT 3
-#define XFS_REMOVE_LOG_COUNT 2
-#define XFS_LINK_LOG_COUNT 2
-#define XFS_RENAME_LOG_COUNT 2
-#define XFS_WRITE_LOG_COUNT 2
-#define XFS_ADDAFORK_LOG_COUNT 2
-#define XFS_ATTRINVAL_LOG_COUNT 1
-#define XFS_ATTRSET_LOG_COUNT 3
-#define XFS_ATTRRM_LOG_COUNT 3
-
-/*
* Here we centralize the specification of XFS meta-data buffer
* reference count values. This determine how hard the buffer
* cache tries to hold onto the buffer.
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
new file mode 100644
index 0000000..cc8260e
--- /dev/null
+++ b/include/xfs_trans_resv.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_TRANS_RESV_H__
+#define __XFS_TRANS_RESV_H__
+
+struct xfs_mount;
+
+/*
+ * structure for maintaining pre-calculated transaction reservations.
+ */
+struct xfs_trans_resv {
+ uint tr_write; /* extent alloc trans */
+ uint tr_itruncate; /* truncate trans */
+ uint tr_rename; /* rename trans */
+ uint tr_link; /* link trans */
+ uint tr_remove; /* unlink trans */
+ uint tr_symlink; /* symlink trans */
+ uint tr_create; /* create trans */
+ uint tr_mkdir; /* mkdir trans */
+ uint tr_ifree; /* inode free trans */
+ uint tr_ichange; /* inode update trans */
+ uint tr_growdata; /* fs data section grow trans */
+ uint tr_swrite; /* sync write inode trans */
+ uint tr_addafork; /* cvt inode to attributed trans */
+ uint tr_writeid; /* write setuid/setgid file */
+ uint tr_attrinval; /* attr fork buffer invalidation */
+ uint tr_attrsetm; /* set/create an attribute at mount time */
+ uint tr_attrsetrt; /* set/create an attribute at runtime */
+ uint tr_attrrm; /* remove an attribute */
+ uint tr_clearagi; /* clear bad agi unlinked ino bucket */
+ uint tr_growrtalloc; /* grow realtime allocations */
+ uint tr_growrtzero; /* grow realtime zeroing */
+ uint tr_growrtfree; /* grow realtime freeing */
+ uint tr_qm_sbchange; /* change quota flags */
+ uint tr_qm_setqlim; /* adjust quota limits */
+ uint tr_qm_dqalloc; /* allocate quota on disk */
+ uint tr_qm_quotaoff; /* turn quota off */
+ uint tr_qm_equotaoff;/* end of turn quota off */
+ uint tr_sb; /* modify superblock */
+};
+
+/*
+ * Per-extent log reservation for the allocation btree changes
+ * involved in freeing or allocating an extent.
+ * 2 trees * (2 blocks/level * max depth - 1) * block size
+ */
+#define XFS_ALLOCFREE_LOG_RES(mp,nx) \
+ ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1)))
+#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
+ ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1)))
+
+/*
+ * Per-directory log reservation for any directory change.
+ * dir blocks: (1 btree block per level + data block + free block) * dblock size
+ * bmap btree: (levels + 2) * max depth * block size
+ * v2 directory blocks can be fragmented below the dirblksize down to the fsb
+ * size, so account for that in the DAENTER macros.
+ */
+#define XFS_DIROP_LOG_RES(mp) \
+ (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
+ (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
+#define XFS_DIROP_LOG_COUNT(mp) \
+ (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
+ XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
+
+
+#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
+#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
+#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
+#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
+#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
+#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
+#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
+#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
+#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
+#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
+#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
+#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
+#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
+#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
+#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
+/*
+ * Logging the inode timestamps on an fsync -- same as SWRITE
+ * as long as SWRITE logs the entire inode core
+ */
+#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
+#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
+#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
+#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
+#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm)
+#define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt)
+#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
+#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
+#define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange)
+#define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim)
+#define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc)
+#define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff)
+#define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff)
+#define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb)
+
+/*
+ * Various log count values.
+ */
+#define XFS_DEFAULT_LOG_COUNT 1
+#define XFS_DEFAULT_PERM_LOG_COUNT 2
+#define XFS_ITRUNCATE_LOG_COUNT 2
+#define XFS_INACTIVE_LOG_COUNT 2
+#define XFS_CREATE_LOG_COUNT 2
+#define XFS_MKDIR_LOG_COUNT 3
+#define XFS_SYMLINK_LOG_COUNT 3
+#define XFS_REMOVE_LOG_COUNT 2
+#define XFS_LINK_LOG_COUNT 2
+#define XFS_RENAME_LOG_COUNT 2
+#define XFS_WRITE_LOG_COUNT 2
+#define XFS_ADDAFORK_LOG_COUNT 2
+#define XFS_ATTRINVAL_LOG_COUNT 1
+#define XFS_ATTRSET_LOG_COUNT 3
+#define XFS_ATTRRM_LOG_COUNT 3
+
+void xfs_trans_resv_calc(struct xfs_mount *mp, struct xfs_trans_resv *resp);
+
+#endif /* __XFS_TRANS_RESV_H__ */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index d0b483d..b19ff6c 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -16,8 +16,11 @@ CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \
xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \
xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \
- xfs_mount.c xfs_rtalloc.c xfs_trans.c xfs_attr.c xfs_attr_remote.c \
- crc32.c xfs_symlink.c
+ xfs_mount.c xfs_rtalloc.c xfs_attr.c xfs_attr_remote.c \
+ crc32.c \
+ xfs_symlink.c \
+ xfs_trans.c \
+ xfs_trans_resv.c
CFILES += $(PKG_PLATFORM).c
PCFILES = darwin.c freebsd.c irix.c linux.c
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index c9d6a6d..66fca85 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -100,6 +100,8 @@ typedef __uint32_t inst_t; /* an instruction */
#define __return_address __builtin_return_address(0)
#endif
+#define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1
+
/* miscellaneous kernel routines not in user space */
#define down_read(a) ((void) 0)
#define up_read(a) ((void) 0)
diff --git a/libxfs/xfs_trans.c b/libxfs/xfs_trans.c
index 95fb630..2daf545 100644
--- a/libxfs/xfs_trans.c
+++ b/libxfs/xfs_trans.c
@@ -23,557 +23,6 @@ kmem_zone_t *xfs_trans_zone;
kmem_zone_t *xfs_log_item_desc_zone;
/*
- * A buffer has a format structure overhead in the log in addition
- * to the data, so we need to take this into account when reserving
- * space in a transaction for a buffer. Round the space required up
- * to a multiple of 128 bytes so that we don't change the historical
- * reservation that has been used for this overhead.
- */
-STATIC uint
-xfs_buf_log_overhead(void)
-{
- return round_up(sizeof(struct xlog_op_header) +
- sizeof(struct xfs_buf_log_format), 128);
-}
-
-/*
- * Calculate out transaction log reservation per item in bytes.
- *
- * The nbufs argument is used to indicate the number of items that
- * will be changed in a transaction. size is used to tell how many
- * bytes should be reserved per item.
- */
-STATIC uint
-xfs_calc_buf_res(
- uint nbufs,
- uint size)
-{
- return nbufs * (size + xfs_buf_log_overhead());
-}
-
-/*
- * Various log reservation values.
- *
- * These are based on the size of the file system block because that is what
- * most transactions manipulate. Each adds in an additional 128 bytes per
- * item logged to try to account for the overhead of the transaction mechanism.
- *
- * Note: Most of the reservations underestimate the number of allocation
- * groups into which they could free extents in the xfs_bmap_finish() call.
- * This is because the number in the worst case is quite high and quite
- * unusual. In order to fix this we need to change xfs_bmap_finish() to free
- * extents in only a single AG at a time. This will require changes to the
- * EFI code as well, however, so that the EFI for the extents not freed is
- * logged again in each transaction. See SGI PV #261917.
- *
- * Reservation functions here avoid a huge stack in xfs_trans_init due to
- * register overflow from temporaries in the calculations.
- */
-
-
-/*
- * In a write transaction we can allocate a maximum of 2
- * extents. This gives:
- * the inode getting the new extents: inode size
- * the inode's bmap btree: max depth * block size
- * the agfs of the ags from which the extents are allocated: 2 * sector
- * the superblock free block counter: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- * And the bmap_finish transaction can free bmap blocks in a join:
- * the agfs of the ags containing the blocks: 2 * sector size
- * the agfls of the ags containing the blocks: 2 * sector size
- * the super block free block counter: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_write_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * In truncating a file we free up to two extents at once. We can modify:
- * the inode being truncated: inode size
- * the inode's bmap btree: (max depth + 1) * block size
- * And the bmap_finish transaction can free the blocks and bmap blocks:
- * the agf for each of the ags: 4 * sector size
- * the agfl for each of the ags: 4 * sector size
- * the super block to reflect the freed blocks: sector size
- * worst case split in allocation btrees per extent assuming 4 extents:
- * 4 exts * 2 trees * (2 * max depth - 1) * block size
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_itruncate_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1,
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(5, 0) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
- mp->m_in_maxlevels, 0)));
-}
-
-/*
- * In renaming a files we can modify:
- * the four inodes involved: 4 * inode size
- * the two directory btrees: 2 * (max depth + v2) * dir block size
- * the two directory bmap btrees: 2 * max depth * block size
- * And the bmap_finish transaction can free dir and bmap blocks (two sets
- * of bmap blocks) giving:
- * the agf for the ags in which the blocks live: 3 * sector size
- * the agfl for the ags in which the blocks live: 3 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_rename_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(4, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * For creating a link to an inode:
- * the parent directory inode: inode size
- * the linked inode: inode size
- * the directory btree could split: (max depth + v2) * dir block size
- * the directory bmap btree could join or split: (max depth + v2) * blocksize
- * And the bmap_finish transaction can free some bmap blocks giving:
- * the agf for the ag in which the blocks live: sector size
- * the agfl for the ag in which the blocks live: sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_link_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * For removing a directory entry we can modify:
- * the parent directory inode: inode size
- * the removed inode: inode size
- * the directory btree could join: (max depth + v2) * dir block size
- * the directory bmap btree could join or split: (max depth + v2) * blocksize
- * And the bmap_finish transaction can free the dir and bmap blocks giving:
- * the agf for the ag in which the blocks live: 2 * sector size
- * the agfl for the ag in which the blocks live: 2 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_remove_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * For create, break it in to the two cases that the transaction
- * covers. We start with the modify case - allocation done by modification
- * of the state of existing inodes - and the allocation case.
- */
-
-/*
- * For create we can modify:
- * the parent directory inode: inode size
- * the new inode: inode size
- * the inode btree entry: block size
- * the superblock for the nlink flag: sector size
- * the directory btree: (max depth + v2) * dir block size
- * the directory inode's bmap btree: (max depth + v2) * block size
- */
-STATIC uint
-xfs_calc_create_resv_modify(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
- (uint)XFS_FSB_TO_B(mp, 1) +
- xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * For create we can allocate some inodes giving:
- * the agi and agf of the ag getting the new inodes: 2 * sectorsize
- * the superblock for the nlink flag: sector size
- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_create_resv_alloc(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- mp->m_sb.sb_sectsize +
- xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-STATIC uint
-__xfs_calc_create_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX(xfs_calc_create_resv_alloc(mp),
- xfs_calc_create_resv_modify(mp));
-}
-
-/*
- * For icreate we can allocate some inodes giving:
- * the agi and agf of the ag getting the new inodes: 2 * sectorsize
- * the superblock for the nlink flag: sector size
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_icreate_resv_alloc(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- mp->m_sb.sb_sectsize +
- xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-STATIC uint
-xfs_calc_icreate_reservation(xfs_mount_t *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX(xfs_calc_icreate_resv_alloc(mp),
- xfs_calc_create_resv_modify(mp));
-}
-
-STATIC uint
-xfs_calc_create_reservation(
- struct xfs_mount *mp)
-{
- if (xfs_sb_version_hascrc(&mp->m_sb))
- return xfs_calc_icreate_reservation(mp);
- return __xfs_calc_create_reservation(mp);
-
-}
-
-/*
- * Making a new directory is the same as creating a new file.
- */
-STATIC uint
-xfs_calc_mkdir_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_create_reservation(mp);
-}
-
-
-/*
- * Making a new symplink is the same as creating a new file, but
- * with the added blocks for remote symlink data which can be up to 1kB in
- * length (MAXPATHLEN).
- */
-STATIC uint
-xfs_calc_symlink_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_create_reservation(mp) +
- xfs_calc_buf_res(1, MAXPATHLEN);
-}
-
-/*
- * In freeing an inode we can modify:
- * the inode being freed: inode size
- * the super block free inode counter: sector size
- * the agi hash list and counters: sector size
- * the inode btree entry: block size
- * the on disk inode before ours in the agi hash list: inode cluster size
- * the inode btree: max depth * blocksize
- * the allocation btrees: 2 trees * (max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_ifree_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
- MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),
- XFS_INODE_CLUSTER_SIZE(mp)) +
- xfs_calc_buf_res(1, 0) +
- xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
- mp->m_in_maxlevels, 0) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * When only changing the inode we log the inode and possibly the superblock
- * We also add a bit of slop for the transaction stuff.
- */
-STATIC uint
-xfs_calc_ichange_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- mp->m_sb.sb_inodesize +
- mp->m_sb.sb_sectsize +
- 512;
-
-}
-
-/*
- * Growing the data section of the filesystem.
- * superblock
- * agi and agf
- * allocation btrees
- */
-STATIC uint
-xfs_calc_growdata_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * Growing the rt section of the filesystem.
- * In the first set of transactions (ALLOC) we allocate space to the
- * bitmap or summary files.
- * superblock: sector size
- * agf of the ag from which the extent is allocated: sector size
- * bmap btree for bitmap/summary inode: max depth * blocksize
- * bitmap/summary inode: inode size
- * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
- */
-STATIC uint
-xfs_calc_growrtalloc_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * Growing the rt section of the filesystem.
- * In the second set of transactions (ZERO) we zero the new metadata blocks.
- * one bitmap/summary block: blocksize
- */
-STATIC uint
-xfs_calc_growrtzero_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize);
-}
-
-/*
- * Growing the rt section of the filesystem.
- * In the third set of transactions (FREE) we update metadata without
- * allocating any new blocks.
- * superblock: sector size
- * bitmap inode: inode size
- * summary inode: inode size
- * one bitmap block: blocksize
- * summary blocks: new summary size
- */
-STATIC uint
-xfs_calc_growrtfree_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) +
- xfs_calc_buf_res(1, mp->m_rsumsize);
-}
-
-/*
- * Logging the inode modification timestamp on a synchronous write.
- * inode
- */
-STATIC uint
-xfs_calc_swrite_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_inodesize);
-}
-
-/*
- * Logging the inode mode bits when writing a setuid/setgid file
- * inode
- */
-STATIC uint
-xfs_calc_writeid_reservation(xfs_mount_t *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_inodesize);
-}
-
-/*
- * Converting the inode from non-attributed to attributed.
- * the inode being converted: inode size
- * agf block and superblock (for block allocation)
- * the new block (directory sized)
- * bmap blocks for the new directory block
- * allocation btrees
- */
-STATIC uint
-xfs_calc_addafork_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(1, mp->m_dirblksize) +
- xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
- XFS_FSB_TO_B(mp, 1)) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
- XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * Removing the attribute fork of a file
- * the inode being truncated: inode size
- * the inode's bmap btree: max depth * block size
- * And the bmap_finish transaction can free the blocks and bmap blocks:
- * the agf for each of the ags: 4 * sector size
- * the agfl for each of the ags: 4 * sector size
- * the super block to reflect the freed blocks: sector size
- * worst case split in allocation btrees per extent assuming 4 extents:
- * 4 exts * 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_attrinval_reservation(
- struct xfs_mount *mp)
-{
- return MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
- XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * Setting an attribute at mount time.
- * the inode getting the attribute
- * the superblock for allocations
- * the agfs extents are allocated from
- * the attribute btree * max depth
- * the inode allocation btree
- * Since attribute transaction space is dependent on the size of the attribute,
- * the calculation is done partially at mount time and partially at runtime(see
- * below).
- */
-STATIC uint
-xfs_calc_attrsetm_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * Setting an attribute at runtime, transaction space unit per block.
- * the superblock for allocations: sector size
- * the inode bmap btree could join or split: max depth * block size
- * Since the runtime attribute transaction space is dependent on the total
- * blocks needed for the 1st bmap, here we calculate out the space unit for
- * one block so that the caller could figure out the total space according
- * to the attibute extent length in blocks by: ext * XFS_ATTRSETRT_LOG_RES(mp).
- */
-STATIC uint
-xfs_calc_attrsetrt_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
- XFS_FSB_TO_B(mp, 1));
-}
-
-/*
- * Removing an attribute.
- * the inode: inode size
- * the attribute btree could join: max depth * block size
- * the inode bmap btree could join or split: max depth * block size
- * And the bmap_finish transaction can free the attr blocks freed giving:
- * the agf for the ag in which the blocks live: 2 * sector size
- * the agfl for the ag in which the blocks live: 2 * sector size
- * the superblock for the free block count: sector size
- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
- */
-STATIC uint
-xfs_calc_attrrm_reservation(
- struct xfs_mount *mp)
-{
- return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
- xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH,
- XFS_FSB_TO_B(mp, 1)) +
- XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
- xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)),
- (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
- xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
- XFS_FSB_TO_B(mp, 1))));
-}
-
-/*
- * Clearing a bad agino number in an agi hash bucket.
- */
-STATIC uint
-xfs_calc_clear_agi_bucket_reservation(
- struct xfs_mount *mp)
-{
- return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
-}
-
-/*
* Initialize the precomputed transaction reservation values
* in the mount structure.
*/
@@ -581,30 +30,7 @@ void
xfs_trans_init(
struct xfs_mount *mp)
{
- struct xfs_trans_reservations *resp = &mp->m_reservations;
-
- resp->tr_write = xfs_calc_write_reservation(mp);
- resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
- resp->tr_rename = xfs_calc_rename_reservation(mp);
- resp->tr_link = xfs_calc_link_reservation(mp);
- resp->tr_remove = xfs_calc_remove_reservation(mp);
- resp->tr_symlink = xfs_calc_symlink_reservation(mp);
- resp->tr_create = xfs_calc_create_reservation(mp);
- resp->tr_mkdir = xfs_calc_mkdir_reservation(mp);
- resp->tr_ifree = xfs_calc_ifree_reservation(mp);
- resp->tr_ichange = xfs_calc_ichange_reservation(mp);
- resp->tr_growdata = xfs_calc_growdata_reservation(mp);
- resp->tr_swrite = xfs_calc_swrite_reservation(mp);
- resp->tr_writeid = xfs_calc_writeid_reservation(mp);
- resp->tr_addafork = xfs_calc_addafork_reservation(mp);
- resp->tr_attrinval = xfs_calc_attrinval_reservation(mp);
- resp->tr_attrsetm = xfs_calc_attrsetm_reservation(mp);
- resp->tr_attrsetrt = xfs_calc_attrsetrt_reservation(mp);
- resp->tr_attrrm = xfs_calc_attrrm_reservation(mp);
- resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp);
- resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp);
- resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp);
- resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp);
+ xfs_trans_resv_calc(mp, &mp->m_reservations);
}
/*
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
new file mode 100644
index 0000000..7a391e3
--- /dev/null
+++ b/libxfs/xfs_trans_resv.c
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * Copyright (C) 2010 Red Hat, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <xfs.h>
+
+/*
+ * A buffer has a format structure overhead in the log in addition
+ * to the data, so we need to take this into account when reserving
+ * space in a transaction for a buffer. Round the space required up
+ * to a multiple of 128 bytes so that we don't change the historical
+ * reservation that has been used for this overhead.
+ */
+STATIC uint
+xfs_buf_log_overhead(void)
+{
+ return round_up(sizeof(struct xlog_op_header) +
+ sizeof(struct xfs_buf_log_format), 128);
+}
+
+/*
+ * Calculate out transaction log reservation per item in bytes.
+ *
+ * The nbufs argument is used to indicate the number of items that
+ * will be changed in a transaction. size is used to tell how many
+ * bytes should be reserved per item.
+ */
+STATIC uint
+xfs_calc_buf_res(
+ uint nbufs,
+ uint size)
+{
+ return nbufs * (size + xfs_buf_log_overhead());
+}
+
+/*
+ * Various log reservation values.
+ *
+ * These are based on the size of the file system block because that is what
+ * most transactions manipulate. Each adds in an additional 128 bytes per
+ * item logged to try to account for the overhead of the transaction mechanism.
+ *
+ * Note: Most of the reservations underestimate the number of allocation
+ * groups into which they could free extents in the xfs_bmap_finish() call.
+ * This is because the number in the worst case is quite high and quite
+ * unusual. In order to fix this we need to change xfs_bmap_finish() to free
+ * extents in only a single AG at a time. This will require changes to the
+ * EFI code as well, however, so that the EFI for the extents not freed is
+ * logged again in each transaction. See SGI PV #261917.
+ *
+ * Reservation functions here avoid a huge stack in xfs_trans_init due to
+ * register overflow from temporaries in the calculations.
+ */
+
+
+/*
+ * In a write transaction we can allocate a maximum of 2
+ * extents. This gives:
+ * the inode getting the new extents: inode size
+ * the inode's bmap btree: max depth * block size
+ * the agfs of the ags from which the extents are allocated: 2 * sector
+ * the superblock free block counter: sector size
+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
+ * And the bmap_finish transaction can free bmap blocks in a join:
+ * the agfs of the ags containing the blocks: 2 * sector size
+ * the agfls of the ags containing the blocks: 2 * sector size
+ * the super block free block counter: sector size
+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_write_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * In truncating a file we free up to two extents at once. We can modify:
+ * the inode being truncated: inode size
+ * the inode's bmap btree: (max depth + 1) * block size
+ * And the bmap_finish transaction can free the blocks and bmap blocks:
+ * the agf for each of the ags: 4 * sector size
+ * the agfl for each of the ags: 4 * sector size
+ * the super block to reflect the freed blocks: sector size
+ * worst case split in allocation btrees per extent assuming 4 extents:
+ * 4 exts * 2 trees * (2 * max depth - 1) * block size
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_itruncate_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1,
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4),
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(5, 0) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
+ mp->m_in_maxlevels, 0)));
+}
+
+/*
+ * In renaming a files we can modify:
+ * the four inodes involved: 4 * inode size
+ * the two directory btrees: 2 * (max depth + v2) * dir block size
+ * the two directory bmap btrees: 2 * max depth * block size
+ * And the bmap_finish transaction can free dir and bmap blocks (two sets
+ * of bmap blocks) giving:
+ * the agf for the ags in which the blocks live: 3 * sector size
+ * the agfl for the ags in which the blocks live: 3 * sector size
+ * the superblock for the free block count: sector size
+ * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_rename_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(4, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp),
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * For creating a link to an inode:
+ * the parent directory inode: inode size
+ * the linked inode: inode size
+ * the directory btree could split: (max depth + v2) * dir block size
+ * the directory bmap btree could join or split: (max depth + v2) * blocksize
+ * And the bmap_finish transaction can free some bmap blocks giving:
+ * the agf for the ag in which the blocks live: sector size
+ * the agfl for the ag in which the blocks live: sector size
+ * the superblock for the free block count: sector size
+ * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_link_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * For removing a directory entry we can modify:
+ * the parent directory inode: inode size
+ * the removed inode: inode size
+ * the directory btree could join: (max depth + v2) * dir block size
+ * the directory bmap btree could join or split: (max depth + v2) * blocksize
+ * And the bmap_finish transaction can free the dir and bmap blocks giving:
+ * the agf for the ag in which the blocks live: 2 * sector size
+ * the agfl for the ag in which the blocks live: 2 * sector size
+ * the superblock for the free block count: sector size
+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_remove_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * For create, break it in to the two cases that the transaction
+ * covers. We start with the modify case - allocation done by modification
+ * of the state of existing inodes - and the allocation case.
+ */
+
+/*
+ * For create we can modify:
+ * the parent directory inode: inode size
+ * the new inode: inode size
+ * the inode btree entry: block size
+ * the superblock for the nlink flag: sector size
+ * the directory btree: (max depth + v2) * dir block size
+ * the directory inode's bmap btree: (max depth + v2) * block size
+ */
+STATIC uint
+xfs_calc_create_resv_modify(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ (uint)XFS_FSB_TO_B(mp, 1) +
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * For create we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+ * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_create_resv_alloc(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+ xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+STATIC uint
+__xfs_calc_create_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX(xfs_calc_create_resv_alloc(mp),
+ xfs_calc_create_resv_modify(mp));
+}
+
+/*
+ * For icreate we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_icreate_resv_alloc(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+STATIC uint
+xfs_calc_icreate_reservation(xfs_mount_t *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX(xfs_calc_icreate_resv_alloc(mp),
+ xfs_calc_create_resv_modify(mp));
+}
+
+STATIC uint
+xfs_calc_create_reservation(
+ struct xfs_mount *mp)
+{
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ return xfs_calc_icreate_reservation(mp);
+ return __xfs_calc_create_reservation(mp);
+
+}
+
+/*
+ * Making a new directory is the same as creating a new file.
+ */
+STATIC uint
+xfs_calc_mkdir_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_create_reservation(mp);
+}
+
+
+/*
+ * Making a new symplink is the same as creating a new file, but
+ * with the added blocks for remote symlink data which can be up to 1kB in
+ * length (MAXPATHLEN).
+ */
+STATIC uint
+xfs_calc_symlink_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_create_reservation(mp) +
+ xfs_calc_buf_res(1, MAXPATHLEN);
+}
+
+/*
+ * In freeing an inode we can modify:
+ * the inode being freed: inode size
+ * the super block free inode counter: sector size
+ * the agi hash list and counters: sector size
+ * the inode btree entry: block size
+ * the on disk inode before ours in the agi hash list: inode cluster size
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_ifree_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
+ MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),
+ XFS_INODE_CLUSTER_SIZE(mp)) +
+ xfs_calc_buf_res(1, 0) +
+ xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
+ mp->m_in_maxlevels, 0) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * When only changing the inode we log the inode and possibly the superblock
+ * We also add a bit of slop for the transaction stuff.
+ */
+STATIC uint
+xfs_calc_ichange_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ mp->m_sb.sb_inodesize +
+ mp->m_sb.sb_sectsize +
+ 512;
+
+}
+
+/*
+ * Growing the data section of the filesystem.
+ * superblock
+ * agi and agf
+ * allocation btrees
+ */
+STATIC uint
+xfs_calc_growdata_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * Growing the rt section of the filesystem.
+ * In the first set of transactions (ALLOC) we allocate space to the
+ * bitmap or summary files.
+ * superblock: sector size
+ * agf of the ag from which the extent is allocated: sector size
+ * bmap btree for bitmap/summary inode: max depth * blocksize
+ * bitmap/summary inode: inode size
+ * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
+ */
+STATIC uint
+xfs_calc_growrtalloc_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * Growing the rt section of the filesystem.
+ * In the second set of transactions (ZERO) we zero the new metadata blocks.
+ * one bitmap/summary block: blocksize
+ */
+STATIC uint
+xfs_calc_growrtzero_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize);
+}
+
+/*
+ * Growing the rt section of the filesystem.
+ * In the third set of transactions (FREE) we update metadata without
+ * allocating any new blocks.
+ * superblock: sector size
+ * bitmap inode: inode size
+ * summary inode: inode size
+ * one bitmap block: blocksize
+ * summary blocks: new summary size
+ */
+STATIC uint
+xfs_calc_growrtfree_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) +
+ xfs_calc_buf_res(1, mp->m_rsumsize);
+}
+
+/*
+ * Logging the inode modification timestamp on a synchronous write.
+ * inode
+ */
+STATIC uint
+xfs_calc_swrite_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_inodesize);
+}
+
+/*
+ * Logging the inode mode bits when writing a setuid/setgid file
+ * inode
+ */
+STATIC uint
+xfs_calc_writeid_reservation(xfs_mount_t *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_inodesize);
+}
+
+/*
+ * Converting the inode from non-attributed to attributed.
+ * the inode being converted: inode size
+ * agf block and superblock (for block allocation)
+ * the new block (directory sized)
+ * bmap blocks for the new directory block
+ * allocation btrees
+ */
+STATIC uint
+xfs_calc_addafork_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(1, mp->m_dirblksize) +
+ xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * Removing the attribute fork of a file
+ * the inode being truncated: inode size
+ * the inode's bmap btree: max depth * block size
+ * And the bmap_finish transaction can free the blocks and bmap blocks:
+ * the agf for each of the ags: 4 * sector size
+ * the agfl for each of the ags: 4 * sector size
+ * the super block to reflect the freed blocks: sector size
+ * worst case split in allocation btrees per extent assuming 4 extents:
+ * 4 exts * 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_attrinval_reservation(
+ struct xfs_mount *mp)
+{
+ return MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * Setting an attribute at mount time.
+ * the inode getting the attribute
+ * the superblock for allocations
+ * the agfs extents are allocated from
+ * the attribute btree * max depth
+ * the inode allocation btree
+ * Since attribute transaction space is dependent on the size of the attribute,
+ * the calculation is done partially at mount time and partially at runtime(see
+ * below).
+ */
+STATIC uint
+xfs_calc_attrsetm_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * Setting an attribute at runtime, transaction space unit per block.
+ * the superblock for allocations: sector size
+ * the inode bmap btree could join or split: max depth * block size
+ * Since the runtime attribute transaction space is dependent on the total
+ * blocks needed for the 1st bmap, here we calculate out the space unit for
+ * one block so that the caller could figure out the total space according
+ * to the attibute extent length in blocks by: ext * XFS_ATTRSETRT_LOG_RES(mp).
+ */
+STATIC uint
+xfs_calc_attrsetrt_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
+ XFS_FSB_TO_B(mp, 1));
+}
+
+/*
+ * Removing an attribute.
+ * the inode: inode size
+ * the attribute btree could join: max depth * block size
+ * the inode bmap btree could join or split: max depth * block size
+ * And the bmap_finish transaction can free the attr blocks freed giving:
+ * the agf for the ag in which the blocks live: 2 * sector size
+ * the agfl for the ag in which the blocks live: 2 * sector size
+ * the superblock for the free block count: sector size
+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
+ */
+STATIC uint
+xfs_calc_attrrm_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_DQUOT_LOGRES(mp) +
+ MAX((xfs_calc_buf_res(1, mp->m_sb.sb_inodesize) +
+ xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH,
+ XFS_FSB_TO_B(mp, 1)) +
+ (uint)XFS_FSB_TO_B(mp,
+ XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
+ xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)),
+ (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
+ XFS_FSB_TO_B(mp, 1))));
+}
+
+/*
+ * Clearing a bad agino number in an agi hash bucket.
+ */
+STATIC uint
+xfs_calc_clear_agi_bucket_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
+}
+
+/*
+ * Clearing the quotaflags in the superblock.
+ * the super block for changing quota flags: sector size
+ */
+STATIC uint
+xfs_calc_qm_sbchange_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
+}
+
+/*
+ * Adjusting quota limits.
+ * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot)
+ */
+STATIC uint
+xfs_calc_qm_setqlim_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, sizeof(struct xfs_disk_dquot));
+}
+
+/*
+ * Allocating quota on disk if needed.
+ * the write transaction log space: XFS_WRITE_LOG_RES(mp)
+ * the unit of quota allocation: one system block size
+ */
+STATIC uint
+xfs_calc_qm_dqalloc_reservation(
+ struct xfs_mount *mp)
+{
+ return XFS_WRITE_LOG_RES(mp) +
+ xfs_calc_buf_res(1,
+ XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
+}
+
+/*
+ * Turning off quotas.
+ * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2
+ * the superblock for the quota flags: sector size
+ */
+STATIC uint
+xfs_calc_qm_quotaoff_reservation(
+ struct xfs_mount *mp)
+{
+ return sizeof(struct xfs_qoff_logitem) * 2 +
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
+}
+
+/*
+ * End of turning off quotas.
+ * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2
+ */
+STATIC uint
+xfs_calc_qm_quotaoff_end_reservation(
+ struct xfs_mount *mp)
+{
+ return sizeof(struct xfs_qoff_logitem) * 2;
+}
+
+/*
+ * Syncing the incore super block changes to disk.
+ * the super block to reflect the changes: sector size
+ */
+STATIC uint
+xfs_calc_sb_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
+}
+
+void
+xfs_trans_resv_calc(
+ struct xfs_mount *mp,
+ struct xfs_trans_resv *resp)
+{
+ resp->tr_write = xfs_calc_write_reservation(mp);
+ resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
+ resp->tr_rename = xfs_calc_rename_reservation(mp);
+ resp->tr_link = xfs_calc_link_reservation(mp);
+ resp->tr_remove = xfs_calc_remove_reservation(mp);
+ resp->tr_symlink = xfs_calc_symlink_reservation(mp);
+ resp->tr_create = xfs_calc_create_reservation(mp);
+ resp->tr_mkdir = xfs_calc_mkdir_reservation(mp);
+ resp->tr_ifree = xfs_calc_ifree_reservation(mp);
+ resp->tr_ichange = xfs_calc_ichange_reservation(mp);
+ resp->tr_growdata = xfs_calc_growdata_reservation(mp);
+ resp->tr_swrite = xfs_calc_swrite_reservation(mp);
+ resp->tr_writeid = xfs_calc_writeid_reservation(mp);
+ resp->tr_addafork = xfs_calc_addafork_reservation(mp);
+ resp->tr_attrinval = xfs_calc_attrinval_reservation(mp);
+ resp->tr_attrsetm = xfs_calc_attrsetm_reservation(mp);
+ resp->tr_attrsetrt = xfs_calc_attrsetrt_reservation(mp);
+ resp->tr_attrrm = xfs_calc_attrrm_reservation(mp);
+ resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp);
+ resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp);
+ resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp);
+ resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp);
+ resp->tr_qm_sbchange = xfs_calc_qm_sbchange_reservation(mp);
+ resp->tr_qm_setqlim = xfs_calc_qm_setqlim_reservation(mp);
+ resp->tr_qm_dqalloc = xfs_calc_qm_dqalloc_reservation(mp);
+ resp->tr_qm_quotaoff = xfs_calc_qm_quotaoff_reservation(mp);
+ resp->tr_qm_equotaoff = xfs_calc_qm_quotaoff_end_reservation(mp);
+ resp->tr_sb = xfs_calc_sb_reservation(mp);
+}
diff --git a/mkfs/maxtrres.c b/mkfs/maxtrres.c
index d571d77..7da83aa 100644
--- a/mkfs/maxtrres.c
+++ b/mkfs/maxtrres.c
@@ -52,11 +52,11 @@ max_attrsetm_trans_res_adjust(
static int
max_trans_res_by_mount(
- xfs_mount_t *mp)
+ struct xfs_mount *mp)
{
- uint *p;
- int rval;
- xfs_trans_reservations_t *tr = &mp->m_reservations;
+ uint *p;
+ int rval;
+ struct xfs_trans_resv *tr = &mp->m_reservations;
for (rval = 0, p = (uint *)tr; p < (uint *)(tr + 1); p++) {
if ((int)*p > rval)
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 26/49] libxfs: move transaction code to trans.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (24 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 25/49] libxfs: introduce xfs_trans_resv.c Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-05 20:51 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 27/49] xfs: move inode fork definitions to a new header file Dave Chinner
` (23 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There is very little code left in xfs_trans.c. So little it is not
worthtrying to share this file with kernel space any more. Move the
code to libxfs/trans.c, and remove libxfs/xfs_trans.c.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/Makefile | 1 -
libxfs/trans.c | 118 +++++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs.h | 6 +++
libxfs/xfs_trans.c | 139 -----------------------------------------------------
4 files changed, 124 insertions(+), 140 deletions(-)
delete mode 100644 libxfs/xfs_trans.c
diff --git a/libxfs/Makefile b/libxfs/Makefile
index b19ff6c..64b5979 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -19,7 +19,6 @@ CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_mount.c xfs_rtalloc.c xfs_attr.c xfs_attr_remote.c \
crc32.c \
xfs_symlink.c \
- xfs_trans.c \
xfs_trans_resv.c
CFILES += $(PKG_PLATFORM).c
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 645952c..d0a91b1 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2000-2001,2005-2006 Silicon Graphics, Inc.
+ * Copyright (C) 2010 Red Hat, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,6 +23,123 @@
* Simple transaction interface
*/
+kmem_zone_t *xfs_log_item_desc_zone;
+
+/*
+ * Initialize the precomputed transaction reservation values
+ * in the mount structure.
+ */
+void
+libxfs_trans_init(
+ struct xfs_mount *mp)
+{
+ xfs_trans_resv_calc(mp, &mp->m_reservations);
+}
+
+/*
+ * Add the given log item to the transaction's list of log items.
+ *
+ * The log item will now point to its new descriptor with its li_desc field.
+ */
+void
+libxfs_trans_add_item(
+ struct xfs_trans *tp,
+ struct xfs_log_item *lip)
+{
+ struct xfs_log_item_desc *lidp;
+
+ ASSERT(lip->li_mountp == tp->t_mountp);
+ ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
+
+ lidp = calloc(sizeof(struct xfs_log_item_desc), 1);
+ if (!lidp) {
+ fprintf(stderr, _("%s: lidp calloc failed (%d bytes): %s\n"),
+ progname, (int)sizeof(struct xfs_log_item_desc),
+ strerror(errno));
+ exit(1);
+ }
+
+ lidp->lid_item = lip;
+ lidp->lid_flags = 0;
+ list_add_tail(&lidp->lid_trans, &tp->t_items);
+
+ lip->li_desc = lidp;
+}
+
+/*
+ * Unlink and free the given descriptor.
+ */
+void
+libxfs_trans_del_item(
+ struct xfs_log_item *lip)
+{
+ list_del_init(&lip->li_desc->lid_trans);
+ free(lip->li_desc);
+ lip->li_desc = NULL;
+}
+
+/*
+ * Roll from one trans in the sequence of PERMANENT transactions to
+ * the next: permanent transactions are only flushed out when
+ * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon
+ * as possible to let chunks of it go to the log. So we commit the
+ * chunk we've been working on and get a new transaction to continue.
+ */
+int
+libxfs_trans_roll(
+ struct xfs_trans **tpp,
+ struct xfs_inode *dp)
+{
+ struct xfs_trans *trans;
+ unsigned int logres, count;
+ int error;
+
+ /*
+ * Ensure that the inode is always logged.
+ */
+ trans = *tpp;
+ xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
+
+ /*
+ * Copy the critical parameters from one trans to the next.
+ */
+ logres = trans->t_log_res;
+ count = trans->t_log_count;
+ *tpp = xfs_trans_dup(trans);
+
+ /*
+ * Commit the current transaction.
+ * If this commit failed, then it'd just unlock those items that
+ * are not marked ihold. That also means that a filesystem shutdown
+ * is in progress. The caller takes the responsibility to cancel
+ * the duplicate transaction that gets returned.
+ */
+ error = xfs_trans_commit(trans, 0);
+ if (error)
+ return (error);
+
+ trans = *tpp;
+
+ /*
+ * Reserve space in the log for th next transaction.
+ * This also pushes items in the "AIL", the list of logged items,
+ * out to disk if they are taking up space at the tail of the log
+ * that we want to use. This requires that either nothing be locked
+ * across this call, or that anything that is locked be logged in
+ * the prior and the next transactions.
+ */
+ error = xfs_trans_reserve(trans, 0, logres, 0,
+ XFS_TRANS_PERM_LOG_RES, count);
+ /*
+ * Ensure that the inode is in the new transaction and locked.
+ */
+ if (error)
+ return error;
+
+ xfs_trans_ijoin(trans, dp, 0);
+ return 0;
+}
+
xfs_trans_t *
libxfs_trans_alloc(
xfs_mount_t *mp,
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 66fca85..7149c09 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -235,12 +235,14 @@ roundup_pow_of_two(uint v)
#define xfs_mod_incore_sb libxfs_mod_incore_sb
#define xfs_trans_alloc libxfs_trans_alloc
+#define xfs_trans_add_item libxfs_trans_add_item
#define xfs_trans_bhold libxfs_trans_bhold
#define xfs_trans_binval libxfs_trans_binval
#define xfs_trans_bjoin libxfs_trans_bjoin
#define xfs_trans_brelse libxfs_trans_brelse
#define xfs_trans_commit libxfs_trans_commit
#define xfs_trans_cancel libxfs_trans_cancel
+#define xfs_trans_del_item libxfs_trans_del_item
#define xfs_trans_dup libxfs_trans_dup
#define xfs_trans_get_buf libxfs_trans_get_buf
#define xfs_trans_getsb libxfs_trans_getsb
@@ -248,12 +250,14 @@ roundup_pow_of_two(uint v)
#define xfs_trans_ihold libxfs_trans_ihold
#define xfs_trans_ijoin libxfs_trans_ijoin
#define xfs_trans_ijoin_ref libxfs_trans_ijoin_ref
+#define xfs_trans_init libxfs_trans_init
#define xfs_trans_inode_alloc_buf libxfs_trans_inode_alloc_buf
#define xfs_trans_log_buf libxfs_trans_log_buf
#define xfs_trans_log_inode libxfs_trans_log_inode
#define xfs_trans_mod_sb libxfs_trans_mod_sb
#define xfs_trans_read_buf libxfs_trans_read_buf
#define xfs_trans_read_buf_map libxfs_trans_read_buf_map
+#define xfs_trans_roll libxfs_trans_roll
#define xfs_trans_get_buf_map libxfs_trans_get_buf_map
#define xfs_trans_reserve libxfs_trans_reserve
@@ -373,6 +377,8 @@ void xfs_mount_common(xfs_mount_t *, xfs_sb_t *);
/*
* logitem.c and trans.c prototypes
*/
+void xfs_trans_init(struct xfs_mount *);
+int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *);
/* xfs_trans_item.c */
void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
diff --git a/libxfs/xfs_trans.c b/libxfs/xfs_trans.c
deleted file mode 100644
index 2daf545..0000000
--- a/libxfs/xfs_trans.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * Copyright (C) 2010 Red Hat, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <xfs.h>
-
-kmem_zone_t *xfs_trans_zone;
-kmem_zone_t *xfs_log_item_desc_zone;
-
-/*
- * Initialize the precomputed transaction reservation values
- * in the mount structure.
- */
-void
-xfs_trans_init(
- struct xfs_mount *mp)
-{
- xfs_trans_resv_calc(mp, &mp->m_reservations);
-}
-
-/*
- * Add the given log item to the transaction's list of log items.
- *
- * The log item will now point to its new descriptor with its li_desc field.
- */
-void
-xfs_trans_add_item(
- struct xfs_trans *tp,
- struct xfs_log_item *lip)
-{
- struct xfs_log_item_desc *lidp;
-
- ASSERT(lip->li_mountp == tp->t_mountp);
- ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
-
- lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS);
-
- lidp->lid_item = lip;
- lidp->lid_flags = 0;
- list_add_tail(&lidp->lid_trans, &tp->t_items);
-
- lip->li_desc = lidp;
-}
-
-STATIC void
-xfs_trans_free_item_desc(
- struct xfs_log_item_desc *lidp)
-{
- list_del_init(&lidp->lid_trans);
- kmem_zone_free(xfs_log_item_desc_zone, lidp);
-}
-
-/*
- * Unlink and free the given descriptor.
- */
-void
-xfs_trans_del_item(
- struct xfs_log_item *lip)
-{
- xfs_trans_free_item_desc(lip->li_desc);
- lip->li_desc = NULL;
-}
-
-/*
- * Roll from one trans in the sequence of PERMANENT transactions to
- * the next: permanent transactions are only flushed out when
- * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon
- * as possible to let chunks of it go to the log. So we commit the
- * chunk we've been working on and get a new transaction to continue.
- */
-int
-xfs_trans_roll(
- struct xfs_trans **tpp,
- struct xfs_inode *dp)
-{
- struct xfs_trans *trans;
- unsigned int logres, count;
- int error;
-
- /*
- * Ensure that the inode is always logged.
- */
- trans = *tpp;
- xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
-
- /*
- * Copy the critical parameters from one trans to the next.
- */
- logres = trans->t_log_res;
- count = trans->t_log_count;
- *tpp = xfs_trans_dup(trans);
-
- /*
- * Commit the current transaction.
- * If this commit failed, then it'd just unlock those items that
- * are not marked ihold. That also means that a filesystem shutdown
- * is in progress. The caller takes the responsibility to cancel
- * the duplicate transaction that gets returned.
- */
- error = xfs_trans_commit(trans, 0);
- if (error)
- return (error);
-
- trans = *tpp;
-
- /*
- * Reserve space in the log for th next transaction.
- * This also pushes items in the "AIL", the list of logged items,
- * out to disk if they are taking up space at the tail of the log
- * that we want to use. This requires that either nothing be locked
- * across this call, or that anything that is locked be logged in
- * the prior and the next transactions.
- */
- error = xfs_trans_reserve(trans, 0, logres, 0,
- XFS_TRANS_PERM_LOG_RES, count);
- /*
- * Ensure that the inode is in the new transaction and locked.
- */
- if (error)
- return error;
-
- xfs_trans_ijoin(trans, dp, 0);
- return 0;
-}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 27/49] xfs: move inode fork definitions to a new header file
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (25 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 26/49] libxfs: move transaction code to trans.c Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-05 21:39 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h Dave Chinner
` (22 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The inode fork definitions are a combination of on-disk format
definition and in-memory tracking and manipulation. They are both
shared with userspace, so move them all into their own file so
sharing is easy to do and track. This removes all inode fork
related information from xfs_inode.h.
Do the same for the all the C code that currently resides in
xfs_inode.c for the same reason.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_bmap_btree.h | 2 +
include/xfs_inode.h | 134 +---
include/xfs_inode_fork.h | 171 +++++
libxfs/Makefile | 7 +-
libxfs/xfs_inode.c | 1878 +--------------------------------------------
libxfs/xfs_inode_fork.c | 1890 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 2072 insertions(+), 2010 deletions(-)
create mode 100644 include/xfs_inode_fork.h
create mode 100644 libxfs/xfs_inode_fork.c
diff --git a/include/xfs_bmap_btree.h b/include/xfs_bmap_btree.h
index 20d66b0..f1069bb 100644
--- a/include/xfs_bmap_btree.h
+++ b/include/xfs_bmap_btree.h
@@ -197,6 +197,8 @@ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
#define XFS_BMDR_SPACE_CALC(nrecs) \
(int)(sizeof(xfs_bmdr_block_t) + \
((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
+#define XFS_BMAP_BMDR_SPACE(bb) \
+ (XFS_BMDR_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs)))
/*
* Maximum number of bmap btree levels.
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 1e92338..6ee8bb7 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -22,58 +22,7 @@ struct posix_acl;
struct xfs_dinode;
struct xfs_inode;
-/*
- * The following xfs_ext_irec_t struct introduces a second (top) level
- * to the in-core extent allocation scheme. These structs are allocated
- * in a contiguous block, creating an indirection array where each entry
- * (irec) contains a pointer to a buffer of in-core extent records which
- * it manages. Each extent buffer is 4k in size, since 4k is the system
- * page size on Linux i386 and systems with larger page sizes don't seem
- * to gain much, if anything, by using their native page size as the
- * extent buffer size. Also, using 4k extent buffers everywhere provides
- * a consistent interface for CXFS across different platforms.
- *
- * There is currently no limit on the number of irec's (extent lists)
- * allowed, so heavily fragmented files may require an indirection array
- * which spans multiple system pages of memory. The number of extents
- * which would require this amount of contiguous memory is very large
- * and should not cause problems in the foreseeable future. However,
- * if the memory needed for the contiguous array ever becomes a problem,
- * it is possible that a third level of indirection may be required.
- */
-typedef struct xfs_ext_irec {
- xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */
- xfs_extnum_t er_extoff; /* extent offset in file */
- xfs_extnum_t er_extcount; /* number of extents in page/block */
-} xfs_ext_irec_t;
-
-/*
- * File incore extent information, present for each of data & attr forks.
- */
-#define XFS_IEXT_BUFSZ 4096
-#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t))
-#define XFS_INLINE_EXTS 2
-#define XFS_INLINE_DATA 32
-typedef struct xfs_ifork {
- int if_bytes; /* bytes in if_u1 */
- int if_real_bytes; /* bytes allocated in if_u1 */
- struct xfs_btree_block *if_broot; /* file's incore btree root */
- short if_broot_bytes; /* bytes allocated for root */
- unsigned char if_flags; /* per-fork flags */
- union {
- xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */
- xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
- char *if_data; /* inline file data */
- } if_u1;
- union {
- xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS];
- /* very small file extents */
- char if_inline_data[XFS_INLINE_DATA];
- /* very small file data */
- xfs_dev_t if_rdev; /* dev number if special */
- uuid_t if_uuid; /* mount point value */
- } if_u2;
-} xfs_ifork_t;
+#include "xfs_inode_fork.h"
/*
* Inode location information. Stored in the inode and passed to
@@ -114,57 +63,6 @@ struct xfs_imap {
#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
-/*
- * Per-fork incore inode flags.
- */
-#define XFS_IFINLINE 0x01 /* Inline data is read in */
-#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */
-#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */
-#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */
-
-/*
- * Fork handling.
- */
-
-#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0)
-#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3))
-
-#define XFS_IFORK_PTR(ip,w) \
- ((w) == XFS_DATA_FORK ? \
- &(ip)->i_df : \
- (ip)->i_afp)
-#define XFS_IFORK_DSIZE(ip) \
- (XFS_IFORK_Q(ip) ? \
- XFS_IFORK_BOFF(ip) : \
- XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version))
-#define XFS_IFORK_ASIZE(ip) \
- (XFS_IFORK_Q(ip) ? \
- XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version) - \
- XFS_IFORK_BOFF(ip) : \
- 0)
-#define XFS_IFORK_SIZE(ip,w) \
- ((w) == XFS_DATA_FORK ? \
- XFS_IFORK_DSIZE(ip) : \
- XFS_IFORK_ASIZE(ip))
-#define XFS_IFORK_FORMAT(ip,w) \
- ((w) == XFS_DATA_FORK ? \
- (ip)->i_d.di_format : \
- (ip)->i_d.di_aformat)
-#define XFS_IFORK_FMT_SET(ip,w,n) \
- ((w) == XFS_DATA_FORK ? \
- ((ip)->i_d.di_format = (n)) : \
- ((ip)->i_d.di_aformat = (n)))
-#define XFS_IFORK_NEXTENTS(ip,w) \
- ((w) == XFS_DATA_FORK ? \
- (ip)->i_d.di_nextents : \
- (ip)->i_d.di_anextents)
-#define XFS_IFORK_NEXT_SET(ip,w,n) \
- ((w) == XFS_DATA_FORK ? \
- ((ip)->i_d.di_nextents = (n)) : \
- ((ip)->i_d.di_anextents = (n)))
-#define XFS_IFORK_MAXEXT(ip, w) \
- (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t))
-
#ifdef __KERNEL__
@@ -515,35 +413,6 @@ int xfs_iread(struct xfs_mount *, struct xfs_trans *,
void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
void xfs_dinode_to_disk(struct xfs_dinode *,
struct xfs_icdinode *);
-void xfs_idestroy_fork(struct xfs_inode *, int);
-void xfs_idata_realloc(struct xfs_inode *, int, int);
-void xfs_iroot_realloc(struct xfs_inode *, int, int);
-int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
-int xfs_iextents_copy(struct xfs_inode *, xfs_bmbt_rec_t *, int);
-
-xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
-void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t,
- xfs_bmbt_irec_t *, int);
-void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int);
-void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int);
-void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int);
-void xfs_iext_realloc_direct(xfs_ifork_t *, int);
-void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
-void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
-void xfs_iext_destroy(xfs_ifork_t *);
-xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
-xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
-xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
-void xfs_iext_irec_init(xfs_ifork_t *);
-xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int);
-void xfs_iext_irec_remove(xfs_ifork_t *, int);
-void xfs_iext_irec_compact(xfs_ifork_t *);
-void xfs_iext_irec_compact_pages(xfs_ifork_t *);
-void xfs_iext_irec_compact_full(xfs_ifork_t *);
-void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
@@ -554,7 +423,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
#define xfs_inobp_check(mp, bp)
#endif /* DEBUG */
-extern struct kmem_zone *xfs_ifork_zone;
extern struct kmem_zone *xfs_inode_zone;
extern const struct xfs_buf_ops xfs_inode_buf_ops;
diff --git a/include/xfs_inode_fork.h b/include/xfs_inode_fork.h
new file mode 100644
index 0000000..28661a0
--- /dev/null
+++ b/include/xfs_inode_fork.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_INODE_FORK_H__
+#define __XFS_INODE_FORK_H__
+
+struct xfs_inode_log_item;
+
+/*
+ * The following xfs_ext_irec_t struct introduces a second (top) level
+ * to the in-core extent allocation scheme. These structs are allocated
+ * in a contiguous block, creating an indirection array where each entry
+ * (irec) contains a pointer to a buffer of in-core extent records which
+ * it manages. Each extent buffer is 4k in size, since 4k is the system
+ * page size on Linux i386 and systems with larger page sizes don't seem
+ * to gain much, if anything, by using their native page size as the
+ * extent buffer size. Also, using 4k extent buffers everywhere provides
+ * a consistent interface for CXFS across different platforms.
+ *
+ * There is currently no limit on the number of irec's (extent lists)
+ * allowed, so heavily fragmented files may require an indirection array
+ * which spans multiple system pages of memory. The number of extents
+ * which would require this amount of contiguous memory is very large
+ * and should not cause problems in the foreseeable future. However,
+ * if the memory needed for the contiguous array ever becomes a problem,
+ * it is possible that a third level of indirection may be required.
+ */
+typedef struct xfs_ext_irec {
+ xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */
+ xfs_extnum_t er_extoff; /* extent offset in file */
+ xfs_extnum_t er_extcount; /* number of extents in page/block */
+} xfs_ext_irec_t;
+
+/*
+ * File incore extent information, present for each of data & attr forks.
+ */
+#define XFS_IEXT_BUFSZ 4096
+#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t))
+#define XFS_INLINE_EXTS 2
+#define XFS_INLINE_DATA 32
+typedef struct xfs_ifork {
+ int if_bytes; /* bytes in if_u1 */
+ int if_real_bytes; /* bytes allocated in if_u1 */
+ struct xfs_btree_block *if_broot; /* file's incore btree root */
+ short if_broot_bytes; /* bytes allocated for root */
+ unsigned char if_flags; /* per-fork flags */
+ union {
+ xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */
+ xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
+ char *if_data; /* inline file data */
+ } if_u1;
+ union {
+ xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS];
+ /* very small file extents */
+ char if_inline_data[XFS_INLINE_DATA];
+ /* very small file data */
+ xfs_dev_t if_rdev; /* dev number if special */
+ uuid_t if_uuid; /* mount point value */
+ } if_u2;
+} xfs_ifork_t;
+
+/*
+ * Per-fork incore inode flags.
+ */
+#define XFS_IFINLINE 0x01 /* Inline data is read in */
+#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */
+#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */
+#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */
+
+/*
+ * Fork handling.
+ */
+
+#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0)
+#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3))
+
+#define XFS_IFORK_PTR(ip,w) \
+ ((w) == XFS_DATA_FORK ? \
+ &(ip)->i_df : \
+ (ip)->i_afp)
+#define XFS_IFORK_DSIZE(ip) \
+ (XFS_IFORK_Q(ip) ? \
+ XFS_IFORK_BOFF(ip) : \
+ XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version))
+#define XFS_IFORK_ASIZE(ip) \
+ (XFS_IFORK_Q(ip) ? \
+ XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version) - \
+ XFS_IFORK_BOFF(ip) : \
+ 0)
+#define XFS_IFORK_SIZE(ip,w) \
+ ((w) == XFS_DATA_FORK ? \
+ XFS_IFORK_DSIZE(ip) : \
+ XFS_IFORK_ASIZE(ip))
+#define XFS_IFORK_FORMAT(ip,w) \
+ ((w) == XFS_DATA_FORK ? \
+ (ip)->i_d.di_format : \
+ (ip)->i_d.di_aformat)
+#define XFS_IFORK_FMT_SET(ip,w,n) \
+ ((w) == XFS_DATA_FORK ? \
+ ((ip)->i_d.di_format = (n)) : \
+ ((ip)->i_d.di_aformat = (n)))
+#define XFS_IFORK_NEXTENTS(ip,w) \
+ ((w) == XFS_DATA_FORK ? \
+ (ip)->i_d.di_nextents : \
+ (ip)->i_d.di_anextents)
+#define XFS_IFORK_NEXT_SET(ip,w,n) \
+ ((w) == XFS_DATA_FORK ? \
+ ((ip)->i_d.di_nextents = (n)) : \
+ ((ip)->i_d.di_anextents = (n)))
+#define XFS_IFORK_MAXEXT(ip, w) \
+ (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t))
+
+int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *);
+void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *,
+ struct xfs_inode_log_item *, int,
+ struct xfs_buf *);
+void xfs_idestroy_fork(struct xfs_inode *, int);
+void xfs_idata_realloc(struct xfs_inode *, int, int);
+void xfs_iroot_realloc(struct xfs_inode *, int, int);
+int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
+int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
+ int);
+
+struct xfs_bmbt_rec_host *
+ xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
+void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t,
+ struct xfs_bmbt_irec *, int);
+void xfs_iext_add(struct xfs_ifork *, xfs_extnum_t, int);
+void xfs_iext_add_indirect_multi(struct xfs_ifork *, int,
+ xfs_extnum_t, int);
+void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int);
+void xfs_iext_remove_inline(struct xfs_ifork *, xfs_extnum_t, int);
+void xfs_iext_remove_direct(struct xfs_ifork *, xfs_extnum_t, int);
+void xfs_iext_remove_indirect(struct xfs_ifork *, xfs_extnum_t, int);
+void xfs_iext_realloc_direct(struct xfs_ifork *, int);
+void xfs_iext_direct_to_inline(struct xfs_ifork *, xfs_extnum_t);
+void xfs_iext_inline_to_direct(struct xfs_ifork *, int);
+void xfs_iext_destroy(struct xfs_ifork *);
+struct xfs_bmbt_rec_host *
+ xfs_iext_bno_to_ext(struct xfs_ifork *, xfs_fileoff_t, int *);
+struct xfs_ext_irec *
+ xfs_iext_bno_to_irec(struct xfs_ifork *, xfs_fileoff_t, int *);
+struct xfs_ext_irec *
+ xfs_iext_idx_to_irec(struct xfs_ifork *, xfs_extnum_t *, int *,
+ int);
+void xfs_iext_irec_init(struct xfs_ifork *);
+struct xfs_ext_irec *
+ xfs_iext_irec_new(struct xfs_ifork *, int);
+void xfs_iext_irec_remove(struct xfs_ifork *, int);
+void xfs_iext_irec_compact(struct xfs_ifork *);
+void xfs_iext_irec_compact_pages(struct xfs_ifork *);
+void xfs_iext_irec_compact_full(struct xfs_ifork *);
+void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int);
+
+extern struct kmem_zone *xfs_ifork_zone;
+
+#endif /* __XFS_INODE_FORK_H__ */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 64b5979..ed978f9 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -12,7 +12,12 @@ LT_AGE = 0
HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h
CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
- xfs_alloc.c xfs_ialloc.c xfs_inode.c xfs_btree.c xfs_alloc_btree.c \
+ xfs_alloc.c \
+ xfs_alloc_btree.c \
+ xfs_btree.c \
+ xfs_ialloc.c \
+ xfs_inode.c \
+ xfs_inode_fork.c \
xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \
xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \
xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \
diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c
index d6513b9..7efe1b3 100644
--- a/libxfs/xfs_inode.c
+++ b/libxfs/xfs_inode.c
@@ -18,7 +18,6 @@
#include <xfs.h>
-kmem_zone_t *xfs_ifork_zone;
kmem_zone_t *xfs_inode_zone;
/*
@@ -27,38 +26,6 @@ kmem_zone_t *xfs_inode_zone;
*/
#define XFS_ITRUNC_MAX_EXTENTS 2
-STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
-STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
-STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
-
-#ifdef DEBUG
-/*
- * Make sure that the extents in the given memory buffer
- * are valid.
- */
-STATIC void
-xfs_validate_extents(
- xfs_ifork_t *ifp,
- int nrecs,
- xfs_exntfmt_t fmt)
-{
- xfs_bmbt_irec_t irec;
- xfs_bmbt_rec_host_t rec;
- int i;
-
- for (i = 0; i < nrecs; i++) {
- xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
- rec.l0 = get_unaligned(&ep->l0);
- rec.l1 = get_unaligned(&ep->l1);
- xfs_bmbt_get_all(&rec, &irec);
- if (fmt == XFS_EXTFMT_NOSTATE)
- ASSERT(irec.br_state == XFS_EXT_NORM);
- }
-}
-#else /* DEBUG */
-#define xfs_validate_extents(ifp, nrecs, fmt)
-#endif /* DEBUG */
-
/*
* Check that none of the inode's in the buffer have a next
* unlinked field of 0.
@@ -193,351 +160,6 @@ xfs_imap_to_bp(
return 0;
}
-/*
- * Move inode type and inode format specific information from the
- * on-disk inode to the in-core inode. For fifos, devs, and sockets
- * this means set if_rdev to the proper value. For files, directories,
- * and symlinks this means to bring in the in-line data or extent
- * pointers. For a file in B-tree format, only the root is immediately
- * brought in-core. The rest will be in-lined in if_extents when it
- * is first referenced (see xfs_iread_extents()).
- */
-STATIC int
-xfs_iformat(
- xfs_inode_t *ip,
- xfs_dinode_t *dip)
-{
- xfs_attr_shortform_t *atp;
- int size;
- int error = 0;
- xfs_fsize_t di_size;
-
- if (unlikely(be32_to_cpu(dip->di_nextents) +
- be16_to_cpu(dip->di_anextents) >
- be64_to_cpu(dip->di_nblocks))) {
- xfs_warn(ip->i_mount,
- "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
- (unsigned long long)ip->i_ino,
- (int)(be32_to_cpu(dip->di_nextents) +
- be16_to_cpu(dip->di_anextents)),
- (unsigned long long)
- be64_to_cpu(dip->di_nblocks));
- XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) {
- xfs_warn(ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.",
- (unsigned long long)ip->i_ino,
- dip->di_forkoff);
- XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
- !ip->i_mount->m_rtdev)) {
- xfs_warn(ip->i_mount,
- "corrupt dinode %Lu, has realtime flag set.",
- ip->i_ino);
- XFS_CORRUPTION_ERROR("xfs_iformat(realtime)",
- XFS_ERRLEVEL_LOW, ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- switch (ip->i_d.di_mode & S_IFMT) {
- case S_IFIFO:
- case S_IFCHR:
- case S_IFBLK:
- case S_IFSOCK:
- if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) {
- XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
- ip->i_d.di_size = 0;
- ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip);
- break;
-
- case S_IFREG:
- case S_IFLNK:
- case S_IFDIR:
- switch (dip->di_format) {
- case XFS_DINODE_FMT_LOCAL:
- /*
- * no local regular files yet
- */
- if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) {
- xfs_warn(ip->i_mount,
- "corrupt inode %Lu (local format for regular file).",
- (unsigned long long) ip->i_ino);
- XFS_CORRUPTION_ERROR("xfs_iformat(4)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- di_size = be64_to_cpu(dip->di_size);
- if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
- xfs_warn(ip->i_mount,
- "corrupt inode %Lu (bad size %Ld for local inode).",
- (unsigned long long) ip->i_ino,
- (long long) di_size);
- XFS_CORRUPTION_ERROR("xfs_iformat(5)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- size = (int)di_size;
- error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
- break;
- case XFS_DINODE_FMT_EXTENTS:
- error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
- break;
- case XFS_DINODE_FMT_BTREE:
- error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
- break;
- default:
- XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- break;
-
- default:
- XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (error) {
- return error;
- }
- if (!XFS_DFORK_Q(dip))
- return 0;
-
- ASSERT(ip->i_afp == NULL);
- ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS);
-
- switch (dip->di_aformat) {
- case XFS_DINODE_FMT_LOCAL:
- atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
- size = be16_to_cpu(atp->hdr.totsize);
-
- if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) {
- xfs_warn(ip->i_mount,
- "corrupt inode %Lu (bad attr fork size %Ld).",
- (unsigned long long) ip->i_ino,
- (long long) size);
- XFS_CORRUPTION_ERROR("xfs_iformat(8)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
- break;
- case XFS_DINODE_FMT_EXTENTS:
- error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
- break;
- case XFS_DINODE_FMT_BTREE:
- error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
- break;
- default:
- error = XFS_ERROR(EFSCORRUPTED);
- break;
- }
- if (error) {
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
- ip->i_afp = NULL;
- xfs_idestroy_fork(ip, XFS_DATA_FORK);
- }
- return error;
-}
-
-/*
- * The file is in-lined in the on-disk inode.
- * If it fits into if_inline_data, then copy
- * it there, otherwise allocate a buffer for it
- * and copy the data there. Either way, set
- * if_data to point at the data.
- * If we allocate a buffer for the data, make
- * sure that its size is a multiple of 4 and
- * record the real size in i_real_bytes.
- */
-STATIC int
-xfs_iformat_local(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork,
- int size)
-{
- xfs_ifork_t *ifp;
- int real_size;
-
- /*
- * If the size is unreasonable, then something
- * is wrong and we just bail out rather than crash in
- * kmem_alloc() or memcpy() below.
- */
- if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
- xfs_warn(ip->i_mount,
- "corrupt inode %Lu (bad size %d for local fork, size = %d).",
- (unsigned long long) ip->i_ino, size,
- XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
- XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
- ifp = XFS_IFORK_PTR(ip, whichfork);
- real_size = 0;
- if (size == 0)
- ifp->if_u1.if_data = NULL;
- else if (size <= sizeof(ifp->if_u2.if_inline_data))
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- else {
- real_size = roundup(size, 4);
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
- }
- ifp->if_bytes = size;
- ifp->if_real_bytes = real_size;
- if (size)
- memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- ifp->if_flags |= XFS_IFINLINE;
- return 0;
-}
-
-/*
- * The file consists of a set of extents all
- * of which fit into the on-disk inode.
- * If there are few enough extents to fit into
- * the if_inline_ext, then copy them there.
- * Otherwise allocate a buffer for them and copy
- * them into it. Either way, set if_extents
- * to point at the extents.
- */
-STATIC int
-xfs_iformat_extents(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork)
-{
- xfs_bmbt_rec_t *dp;
- xfs_ifork_t *ifp;
- int nex;
- int size;
- int i;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
- size = nex * (uint)sizeof(xfs_bmbt_rec_t);
-
- /*
- * If the number of extents is unreasonable, then something
- * is wrong and we just bail out rather than crash in
- * kmem_alloc() or memcpy() below.
- */
- if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
- xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
- (unsigned long long) ip->i_ino, nex);
- XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
- ip->i_mount, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- ifp->if_real_bytes = 0;
- if (nex == 0)
- ifp->if_u1.if_extents = NULL;
- else if (nex <= XFS_INLINE_EXTS)
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- else
- xfs_iext_add(ifp, 0, nex);
-
- ifp->if_bytes = size;
- if (size) {
- dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
- xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
- for (i = 0; i < nex; i++, dp++) {
- xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
- ep->l0 = get_unaligned_be64(&dp->l0);
- ep->l1 = get_unaligned_be64(&dp->l1);
- }
- XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
- if (whichfork != XFS_DATA_FORK ||
- XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
- if (unlikely(xfs_check_nostate_extents(
- ifp, 0, nex))) {
- XFS_ERROR_REPORT("xfs_iformat_extents(2)",
- XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- }
- ifp->if_flags |= XFS_IFEXTENTS;
- return 0;
-}
-
-/*
- * The file has too many extents to fit into
- * the inode, so they are in B-tree format.
- * Allocate a buffer for the root of the B-tree
- * and copy the root into it. The i_extents
- * field will remain NULL until all of the
- * extents are read in (when they are needed).
- */
-STATIC int
-xfs_iformat_btree(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- int whichfork)
-{
- struct xfs_mount *mp = ip->i_mount;
- xfs_bmdr_block_t *dfp;
- xfs_ifork_t *ifp;
- /* REFERENCED */
- int nrecs;
- int size;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
- size = XFS_BMAP_BROOT_SPACE(mp, dfp);
- nrecs = be16_to_cpu(dfp->bb_numrecs);
-
- /*
- * blow out if -- fork has less extents than can fit in
- * fork (fork shouldn't be a btree format), root btree
- * block has more records than can fit into the fork,
- * or the number of extents is greater than the number of
- * blocks.
- */
- if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <=
- XFS_IFORK_MAXEXT(ip, whichfork) ||
- XFS_BMDR_SPACE_CALC(nrecs) >
- XFS_DFORK_SIZE(dip, mp, whichfork) ||
- XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
- xfs_warn(mp, "corrupt inode %Lu (btree).",
- (unsigned long long) ip->i_ino);
- XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
- mp, dip);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- ifp->if_broot_bytes = size;
- ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS);
- ASSERT(ifp->if_broot != NULL);
- /*
- * Copy and convert from the on-disk structure
- * to the in-memory structure.
- */
- xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
- ifp->if_broot, size);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- ifp->if_flags |= XFS_IFBROOT;
-
- return 0;
-}
-
void
xfs_dinode_from_disk(
xfs_icdinode_t *to,
@@ -656,7 +278,6 @@ xfs_dinode_verify(
return false;
return true;
}
-
void
xfs_dinode_calc_crc(
struct xfs_mount *mp,
@@ -714,13 +335,13 @@ xfs_iread(
/*
* If the on-disk inode is already linked to a directory
* entry, copy all of the inode into the in-core inode.
- * xfs_iformat() handles copying in the inode format
+ * xfs_iformat_fork() handles copying in the inode format
* specific information.
* Otherwise, just get the truly permanent information.
*/
if (dip->di_mode) {
xfs_dinode_from_disk(&ip->i_d, dip);
- error = xfs_iformat(ip, dip);
+ error = xfs_iformat_fork(ip, dip);
if (error) {
#ifdef DEBUG
xfs_alert(mp, "%s: xfs_iformat() returned error %d",
@@ -796,1498 +417,3 @@ xfs_iread(
xfs_trans_brelse(tp, bp);
return error;
}
-
-/*
- * Read in extents from a btree-format inode.
- * Allocate and fill in if_extents. Real work is done in xfs_bmap.c.
- */
-int
-xfs_iread_extents(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- int whichfork)
-{
- int error;
- xfs_ifork_t *ifp;
- xfs_extnum_t nextents;
-
- if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
- XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
- ip->i_mount);
- return XFS_ERROR(EFSCORRUPTED);
- }
- nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
- ifp = XFS_IFORK_PTR(ip, whichfork);
-
- /*
- * We know that the size is valid (it's checked in iformat_btree)
- */
- ifp->if_bytes = ifp->if_real_bytes = 0;
- ifp->if_flags |= XFS_IFEXTENTS;
- xfs_iext_add(ifp, 0, nextents);
- error = xfs_bmap_read_extents(tp, ip, whichfork);
- if (error) {
- xfs_iext_destroy(ifp);
- ifp->if_flags &= ~XFS_IFEXTENTS;
- return error;
- }
- xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
- return 0;
-}
-
-/*
- * Reallocate the space for if_broot based on the number of records
- * being added or deleted as indicated in rec_diff. Move the records
- * and pointers in if_broot to fit the new size. When shrinking this
- * will eliminate holes between the records and pointers created by
- * the caller. When growing this will create holes to be filled in
- * by the caller.
- *
- * The caller must not request to add more records than would fit in
- * the on-disk inode root. If the if_broot is currently NULL, then
- * if we adding records one will be allocated. The caller must also
- * not request that the number of records go below zero, although
- * it can go to zero.
- *
- * ip -- the inode whose if_broot area is changing
- * ext_diff -- the change in the number of records, positive or negative,
- * requested for the if_broot array.
- */
-void
-xfs_iroot_realloc(
- xfs_inode_t *ip,
- int rec_diff,
- int whichfork)
-{
- struct xfs_mount *mp = ip->i_mount;
- int cur_max;
- xfs_ifork_t *ifp;
- struct xfs_btree_block *new_broot;
- int new_max;
- size_t new_size;
- char *np;
- char *op;
-
- /*
- * Handle the degenerate case quietly.
- */
- if (rec_diff == 0) {
- return;
- }
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (rec_diff > 0) {
- /*
- * If there wasn't any memory allocated before, just
- * allocate it now and get out.
- */
- if (ifp->if_broot_bytes == 0) {
- new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
- ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
- ifp->if_broot_bytes = (int)new_size;
- return;
- }
-
- /*
- * If there is already an existing if_broot, then we need
- * to realloc() it and shift the pointers to their new
- * location. The records don't change location because
- * they are kept butted up against the btree block header.
- */
- cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
- new_max = cur_max + rec_diff;
- new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
- ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
- XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
- KM_SLEEP | KM_NOFS);
- op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
- ifp->if_broot_bytes);
- np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
- (int)new_size);
- ifp->if_broot_bytes = (int)new_size;
- ASSERT(ifp->if_broot_bytes <=
- XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip));
- memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t));
- return;
- }
-
- /*
- * rec_diff is less than 0. In this case, we are shrinking the
- * if_broot buffer. It must already exist. If we go to zero
- * records, just get rid of the root and clear the status bit.
- */
- ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
- cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
- new_max = cur_max + rec_diff;
- ASSERT(new_max >= 0);
- if (new_max > 0)
- new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
- else
- new_size = 0;
- if (new_size > 0) {
- new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
- /*
- * First copy over the btree block header.
- */
- memcpy(new_broot, ifp->if_broot,
- XFS_BMBT_BLOCK_LEN(ip->i_mount));
- } else {
- new_broot = NULL;
- ifp->if_flags &= ~XFS_IFBROOT;
- }
-
- /*
- * Only copy the records and pointers if there are any.
- */
- if (new_max > 0) {
- /*
- * First copy the records.
- */
- op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
- np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
- memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
-
- /*
- * Then copy the pointers.
- */
- op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
- ifp->if_broot_bytes);
- np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
- (int)new_size);
- memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
- }
- kmem_free(ifp->if_broot);
- ifp->if_broot = new_broot;
- ifp->if_broot_bytes = (int)new_size;
- ASSERT(ifp->if_broot_bytes <=
- XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip));
- return;
-}
-
-
-/*
- * This is called when the amount of space needed for if_data
- * is increased or decreased. The change in size is indicated by
- * the number of bytes that need to be added or deleted in the
- * byte_diff parameter.
- *
- * If the amount of space needed has decreased below the size of the
- * inline buffer, then switch to using the inline buffer. Otherwise,
- * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
- * to what is needed.
- *
- * ip -- the inode whose if_data area is changing
- * byte_diff -- the change in the number of bytes, positive or negative,
- * requested for the if_data array.
- */
-void
-xfs_idata_realloc(
- xfs_inode_t *ip,
- int byte_diff,
- int whichfork)
-{
- xfs_ifork_t *ifp;
- int new_size;
- int real_size;
-
- if (byte_diff == 0) {
- return;
- }
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- new_size = (int)ifp->if_bytes + byte_diff;
- ASSERT(new_size >= 0);
-
- if (new_size == 0) {
- if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- kmem_free(ifp->if_u1.if_data);
- }
- ifp->if_u1.if_data = NULL;
- real_size = 0;
- } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) {
- /*
- * If the valid extents/data can fit in if_inline_ext/data,
- * copy them from the malloc'd vector and free it.
- */
- if (ifp->if_u1.if_data == NULL) {
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- ASSERT(ifp->if_real_bytes != 0);
- memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data,
- new_size);
- kmem_free(ifp->if_u1.if_data);
- ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
- }
- real_size = 0;
- } else {
- /*
- * Stuck with malloc/realloc.
- * For inline data, the underlying buffer must be
- * a multiple of 4 bytes in size so that it can be
- * logged and stay on word boundaries. We enforce
- * that here.
- */
- real_size = roundup(new_size, 4);
- if (ifp->if_u1.if_data == NULL) {
- ASSERT(ifp->if_real_bytes == 0);
- ifp->if_u1.if_data = kmem_alloc(real_size,
- KM_SLEEP | KM_NOFS);
- } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
- /*
- * Only do the realloc if the underlying size
- * is really changing.
- */
- if (ifp->if_real_bytes != real_size) {
- ifp->if_u1.if_data =
- kmem_realloc(ifp->if_u1.if_data,
- real_size,
- ifp->if_real_bytes,
- KM_SLEEP | KM_NOFS);
- }
- } else {
- ASSERT(ifp->if_real_bytes == 0);
- ifp->if_u1.if_data = kmem_alloc(real_size,
- KM_SLEEP | KM_NOFS);
- memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data,
- ifp->if_bytes);
- }
- }
- ifp->if_real_bytes = real_size;
- ifp->if_bytes = new_size;
- ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
-}
-
-void
-xfs_idestroy_fork(
- xfs_inode_t *ip,
- int whichfork)
-{
- xfs_ifork_t *ifp;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (ifp->if_broot != NULL) {
- kmem_free(ifp->if_broot);
- ifp->if_broot = NULL;
- }
-
- /*
- * If the format is local, then we can't have an extents
- * array so just look for an inline data array. If we're
- * not local then we may or may not have an extents list,
- * so check and free it up if we do.
- */
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
- if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) &&
- (ifp->if_u1.if_data != NULL)) {
- ASSERT(ifp->if_real_bytes != 0);
- kmem_free(ifp->if_u1.if_data);
- ifp->if_u1.if_data = NULL;
- ifp->if_real_bytes = 0;
- }
- } else if ((ifp->if_flags & XFS_IFEXTENTS) &&
- ((ifp->if_flags & XFS_IFEXTIREC) ||
- ((ifp->if_u1.if_extents != NULL) &&
- (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) {
- ASSERT(ifp->if_real_bytes != 0);
- xfs_iext_destroy(ifp);
- }
- ASSERT(ifp->if_u1.if_extents == NULL ||
- ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext);
- ASSERT(ifp->if_real_bytes == 0);
- if (whichfork == XFS_ATTR_FORK) {
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
- ip->i_afp = NULL;
- }
-}
-
-/*
- * xfs_iextents_copy()
- *
- * This is called to copy the REAL extents (as opposed to the delayed
- * allocation extents) from the inode into the given buffer. It
- * returns the number of bytes copied into the buffer.
- *
- * If there are no delayed allocation extents, then we can just
- * memcpy() the extents into the buffer. Otherwise, we need to
- * examine each extent in turn and skip those which are delayed.
- */
-int
-xfs_iextents_copy(
- xfs_inode_t *ip,
- xfs_bmbt_rec_t *dp,
- int whichfork)
-{
- int copied;
- int i;
- xfs_ifork_t *ifp;
- int nrecs;
- xfs_fsblock_t start_block;
-
- ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
- ASSERT(ifp->if_bytes > 0);
-
- nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
- ASSERT(nrecs > 0);
-
- /*
- * There are some delayed allocation extents in the
- * inode, so copy the extents one at a time and skip
- * the delayed ones. There must be at least one
- * non-delayed extent.
- */
- copied = 0;
- for (i = 0; i < nrecs; i++) {
- xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
- start_block = xfs_bmbt_get_startblock(ep);
- if (isnullstartblock(start_block)) {
- /*
- * It's a delayed allocation extent, so skip it.
- */
- continue;
- }
-
- /* Translate to on disk format */
- put_unaligned_be64(ep->l0, &dp->l0);
- put_unaligned_be64(ep->l1, &dp->l1);
- dp++;
- copied++;
- }
- ASSERT(copied != 0);
- xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
-
- return (copied * (uint)sizeof(xfs_bmbt_rec_t));
-}
-
-/*
- * Each of the following cases stores data into the same region
- * of the on-disk inode, so only one of them can be valid at
- * any given time. While it is possible to have conflicting formats
- * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
- * in EXTENTS format, this can only happen when the fork has
- * changed formats after being modified but before being flushed.
- * In these cases, the format always takes precedence, because the
- * format indicates the current state of the fork.
- */
-/*ARGSUSED*/
-void
-xfs_iflush_fork(
- xfs_inode_t *ip,
- xfs_dinode_t *dip,
- xfs_inode_log_item_t *iip,
- int whichfork,
- xfs_buf_t *bp)
-{
- char *cp;
- xfs_ifork_t *ifp;
- xfs_mount_t *mp;
-
- static const short brootflag[2] =
- { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
- static const short dataflag[2] =
- { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
- static const short extflag[2] =
- { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
-
- if (!iip)
- return;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- /*
- * This can happen if we gave up in iformat in an error path,
- * for the attribute fork.
- */
- if (!ifp) {
- ASSERT(whichfork == XFS_ATTR_FORK);
- return;
- }
- cp = XFS_DFORK_PTR(dip, whichfork);
- mp = ip->i_mount;
- switch (XFS_IFORK_FORMAT(ip, whichfork)) {
- case XFS_DINODE_FMT_LOCAL:
- if ((iip->ili_fields & dataflag[whichfork]) &&
- (ifp->if_bytes > 0)) {
- ASSERT(ifp->if_u1.if_data != NULL);
- ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
- memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
- }
- break;
-
- case XFS_DINODE_FMT_EXTENTS:
- ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
- !(iip->ili_fields & extflag[whichfork]));
- if ((iip->ili_fields & extflag[whichfork]) &&
- (ifp->if_bytes > 0)) {
- ASSERT(xfs_iext_get_ext(ifp, 0));
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
- (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
- whichfork);
- }
- break;
-
- case XFS_DINODE_FMT_BTREE:
- if ((iip->ili_fields & brootflag[whichfork]) &&
- (ifp->if_broot_bytes > 0)) {
- ASSERT(ifp->if_broot != NULL);
- ASSERT(ifp->if_broot_bytes <=
- (XFS_IFORK_SIZE(ip, whichfork) +
- XFS_BROOT_SIZE_ADJ(ip)));
- xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
- (xfs_bmdr_block_t *)cp,
- XFS_DFORK_SIZE(dip, mp, whichfork));
- }
- break;
-
- case XFS_DINODE_FMT_DEV:
- if (iip->ili_fields & XFS_ILOG_DEV) {
- ASSERT(whichfork == XFS_DATA_FORK);
- xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev);
- }
- break;
-
- case XFS_DINODE_FMT_UUID:
- if (iip->ili_fields & XFS_ILOG_UUID) {
- ASSERT(whichfork == XFS_DATA_FORK);
- memcpy(XFS_DFORK_DPTR(dip),
- &ip->i_df.if_u2.if_uuid,
- sizeof(uuid_t));
- }
- break;
-
- default:
- ASSERT(0);
- break;
- }
-}
-
-/*
- * Return a pointer to the extent record at file index idx.
- */
-xfs_bmbt_rec_host_t *
-xfs_iext_get_ext(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx) /* index of target extent */
-{
- ASSERT(idx >= 0);
- ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
-
- if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
- return ifp->if_u1.if_ext_irec->er_extbuf;
- } else if (ifp->if_flags & XFS_IFEXTIREC) {
- xfs_ext_irec_t *erp; /* irec pointer */
- int erp_idx = 0; /* irec index */
- xfs_extnum_t page_idx = idx; /* ext index in target list */
-
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
- return &erp->er_extbuf[page_idx];
- } else if (ifp->if_bytes) {
- return &ifp->if_u1.if_extents[idx];
- } else {
- return NULL;
- }
-}
-
-/*
- * Insert new item(s) into the extent records for incore inode
- * fork 'ifp'. 'count' new items are inserted at index 'idx'.
- */
-void
-xfs_iext_insert(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* starting index of new items */
- xfs_extnum_t count, /* number of inserted items */
- xfs_bmbt_irec_t *new, /* items to insert */
- int state) /* type of extent conversion */
-{
- xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
- xfs_extnum_t i; /* extent record index */
-
- trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_);
-
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- xfs_iext_add(ifp, idx, count);
- for (i = idx; i < idx + count; i++, new++)
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new);
-}
-
-/*
- * This is called when the amount of space required for incore file
- * extents needs to be increased. The ext_diff parameter stores the
- * number of new extents being added and the idx parameter contains
- * the extent index where the new extents will be added. If the new
- * extents are being appended, then we just need to (re)allocate and
- * initialize the space. Otherwise, if the new extents are being
- * inserted into the middle of the existing entries, a bit more work
- * is required to make room for the new extents to be inserted. The
- * caller is responsible for filling in the new extent entries upon
- * return.
- */
-void
-xfs_iext_add(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin adding exts */
- int ext_diff) /* number of extents to add */
-{
- int byte_diff; /* new bytes being added */
- int new_size; /* size of extents after adding */
- xfs_extnum_t nextents; /* number of extents in file */
-
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT((idx >= 0) && (idx <= nextents));
- byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
- new_size = ifp->if_bytes + byte_diff;
- /*
- * If the new number of extents (nextents + ext_diff)
- * fits inside the inode, then continue to use the inline
- * extent buffer.
- */
- if (nextents + ext_diff <= XFS_INLINE_EXTS) {
- if (idx < nextents) {
- memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff],
- &ifp->if_u2.if_inline_ext[idx],
- (nextents - idx) * sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff);
- }
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- ifp->if_real_bytes = 0;
- }
- /*
- * Otherwise use a linear (direct) extent list.
- * If the extents are currently inside the inode,
- * xfs_iext_realloc_direct will switch us from
- * inline to direct extent allocation mode.
- */
- else if (nextents + ext_diff <= XFS_LINEAR_EXTS) {
- xfs_iext_realloc_direct(ifp, new_size);
- if (idx < nextents) {
- memmove(&ifp->if_u1.if_extents[idx + ext_diff],
- &ifp->if_u1.if_extents[idx],
- (nextents - idx) * sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u1.if_extents[idx], 0, byte_diff);
- }
- }
- /* Indirection array */
- else {
- xfs_ext_irec_t *erp;
- int erp_idx = 0;
- int page_idx = idx;
-
- ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS);
- if (ifp->if_flags & XFS_IFEXTIREC) {
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1);
- } else {
- xfs_iext_irec_init(ifp);
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = ifp->if_u1.if_ext_irec;
- }
- /* Extents fit in target extent page */
- if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) {
- if (page_idx < erp->er_extcount) {
- memmove(&erp->er_extbuf[page_idx + ext_diff],
- &erp->er_extbuf[page_idx],
- (erp->er_extcount - page_idx) *
- sizeof(xfs_bmbt_rec_t));
- memset(&erp->er_extbuf[page_idx], 0, byte_diff);
- }
- erp->er_extcount += ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- }
- /* Insert a new extent page */
- else if (erp) {
- xfs_iext_add_indirect_multi(ifp,
- erp_idx, page_idx, ext_diff);
- }
- /*
- * If extent(s) are being appended to the last page in
- * the indirection array and the new extent(s) don't fit
- * in the page, then erp is NULL and erp_idx is set to
- * the next index needed in the indirection array.
- */
- else {
- int count = ext_diff;
-
- while (count) {
- erp = xfs_iext_irec_new(ifp, erp_idx);
- erp->er_extcount = count;
- count -= MIN(count, (int)XFS_LINEAR_EXTS);
- if (count) {
- erp_idx++;
- }
- }
- }
- }
- ifp->if_bytes = new_size;
-}
-
-/*
- * This is called when incore extents are being added to the indirection
- * array and the new extents do not fit in the target extent list. The
- * erp_idx parameter contains the irec index for the target extent list
- * in the indirection array, and the idx parameter contains the extent
- * index within the list. The number of extents being added is stored
- * in the count parameter.
- *
- * |-------| |-------|
- * | | | | idx - number of extents before idx
- * | idx | | count |
- * | | | | count - number of extents being inserted at idx
- * |-------| |-------|
- * | count | | nex2 | nex2 - number of extents after idx + count
- * |-------| |-------|
- */
-void
-xfs_iext_add_indirect_multi(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx, /* target extent irec index */
- xfs_extnum_t idx, /* index within target list */
- int count) /* new extents being added */
-{
- int byte_diff; /* new bytes being added */
- xfs_ext_irec_t *erp; /* pointer to irec entry */
- xfs_extnum_t ext_diff; /* number of extents to add */
- xfs_extnum_t ext_cnt; /* new extents still needed */
- xfs_extnum_t nex2; /* extents after idx + count */
- xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */
- int nlists; /* number of irec's (lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- nex2 = erp->er_extcount - idx;
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
- /*
- * Save second part of target extent list
- * (all extents past */
- if (nex2) {
- byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
- nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS);
- memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff);
- erp->er_extcount -= nex2;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2);
- memset(&erp->er_extbuf[idx], 0, byte_diff);
- }
-
- /*
- * Add the new extents to the end of the target
- * list, then allocate new irec record(s) and
- * extent buffer(s) as needed to store the rest
- * of the new extents.
- */
- ext_cnt = count;
- ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount);
- if (ext_diff) {
- erp->er_extcount += ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- ext_cnt -= ext_diff;
- }
- while (ext_cnt) {
- erp_idx++;
- erp = xfs_iext_irec_new(ifp, erp_idx);
- ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS);
- erp->er_extcount = ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
- ext_cnt -= ext_diff;
- }
-
- /* Add nex2 extents back to indirection array */
- if (nex2) {
- xfs_extnum_t ext_avail;
- int i;
-
- byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
- ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
- i = 0;
- /*
- * If nex2 extents fit in the current page, append
- * nex2_ep after the new extents.
- */
- if (nex2 <= ext_avail) {
- i = erp->er_extcount;
- }
- /*
- * Otherwise, check if space is available in the
- * next page.
- */
- else if ((erp_idx < nlists - 1) &&
- (nex2 <= (ext_avail = XFS_LINEAR_EXTS -
- ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) {
- erp_idx++;
- erp++;
- /* Create a hole for nex2 extents */
- memmove(&erp->er_extbuf[nex2], erp->er_extbuf,
- erp->er_extcount * sizeof(xfs_bmbt_rec_t));
- }
- /*
- * Final choice, create a new extent page for
- * nex2 extents.
- */
- else {
- erp_idx++;
- erp = xfs_iext_irec_new(ifp, erp_idx);
- }
- memmove(&erp->er_extbuf[i], nex2_ep, byte_diff);
- kmem_free(nex2_ep);
- erp->er_extcount += nex2;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2);
- }
-}
-
-/*
- * This is called when the amount of space required for incore file
- * extents needs to be decreased. The ext_diff parameter stores the
- * number of extents to be removed and the idx parameter contains
- * the extent index where the extents will be removed from.
- *
- * If the amount of space needed has decreased below the linear
- * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous
- * extent array. Otherwise, use kmem_realloc() to adjust the
- * size to what is needed.
- */
-void
-xfs_iext_remove(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff, /* number of extents to remove */
- int state) /* type of extent conversion */
-{
- xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
- xfs_extnum_t nextents; /* number of extents in file */
- int new_size; /* size of extents after removal */
-
- trace_xfs_iext_remove(ip, idx, state, _RET_IP_);
-
- ASSERT(ext_diff > 0);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
-
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- } else if (ifp->if_flags & XFS_IFEXTIREC) {
- xfs_iext_remove_indirect(ifp, idx, ext_diff);
- } else if (ifp->if_real_bytes) {
- xfs_iext_remove_direct(ifp, idx, ext_diff);
- } else {
- xfs_iext_remove_inline(ifp, idx, ext_diff);
- }
- ifp->if_bytes = new_size;
-}
-
-/*
- * This removes ext_diff extents from the inline buffer, beginning
- * at extent index idx.
- */
-void
-xfs_iext_remove_inline(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff) /* number of extents to remove */
-{
- int nextents; /* number of extents in file */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- ASSERT(idx < XFS_INLINE_EXTS);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(((nextents - ext_diff) > 0) &&
- (nextents - ext_diff) < XFS_INLINE_EXTS);
-
- if (idx + ext_diff < nextents) {
- memmove(&ifp->if_u2.if_inline_ext[idx],
- &ifp->if_u2.if_inline_ext[idx + ext_diff],
- (nextents - (idx + ext_diff)) *
- sizeof(xfs_bmbt_rec_t));
- memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff],
- 0, ext_diff * sizeof(xfs_bmbt_rec_t));
- } else {
- memset(&ifp->if_u2.if_inline_ext[idx], 0,
- ext_diff * sizeof(xfs_bmbt_rec_t));
- }
-}
-
-/*
- * This removes ext_diff extents from a linear (direct) extent list,
- * beginning at extent index idx. If the extents are being removed
- * from the end of the list (ie. truncate) then we just need to re-
- * allocate the list to remove the extra space. Otherwise, if the
- * extents are being removed from the middle of the existing extent
- * entries, then we first need to move the extent records beginning
- * at idx + ext_diff up in the list to overwrite the records being
- * removed, then remove the extra space via kmem_realloc.
- */
-void
-xfs_iext_remove_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing exts */
- int ext_diff) /* number of extents to remove */
-{
- xfs_extnum_t nextents; /* number of extents in file */
- int new_size; /* size of extents after removal */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- new_size = ifp->if_bytes -
- (ext_diff * sizeof(xfs_bmbt_rec_t));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
-
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- return;
- }
- /* Move extents up in the list (if needed) */
- if (idx + ext_diff < nextents) {
- memmove(&ifp->if_u1.if_extents[idx],
- &ifp->if_u1.if_extents[idx + ext_diff],
- (nextents - (idx + ext_diff)) *
- sizeof(xfs_bmbt_rec_t));
- }
- memset(&ifp->if_u1.if_extents[nextents - ext_diff],
- 0, ext_diff * sizeof(xfs_bmbt_rec_t));
- /*
- * Reallocate the direct extent list. If the extents
- * will fit inside the inode then xfs_iext_realloc_direct
- * will switch from direct to inline extent allocation
- * mode for us.
- */
- xfs_iext_realloc_direct(ifp, new_size);
- ifp->if_bytes = new_size;
-}
-
-/*
- * This is called when incore extents are being removed from the
- * indirection array and the extents being removed span multiple extent
- * buffers. The idx parameter contains the file extent index where we
- * want to begin removing extents, and the count parameter contains
- * how many extents need to be removed.
- *
- * |-------| |-------|
- * | nex1 | | | nex1 - number of extents before idx
- * |-------| | count |
- * | | | | count - number of extents being removed at idx
- * | count | |-------|
- * | | | nex2 | nex2 - number of extents after idx + count
- * |-------| |-------|
- */
-void
-xfs_iext_remove_indirect(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t idx, /* index to begin removing extents */
- int count) /* number of extents to remove */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int erp_idx = 0; /* indirection array index */
- xfs_extnum_t ext_cnt; /* extents left to remove */
- xfs_extnum_t ext_diff; /* extents to remove in current list */
- xfs_extnum_t nex1; /* number of extents before idx */
- xfs_extnum_t nex2; /* extents after idx + count */
- int page_idx = idx; /* index in target extent list */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
- ASSERT(erp != NULL);
- nex1 = page_idx;
- ext_cnt = count;
- while (ext_cnt) {
- nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0);
- ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1));
- /*
- * Check for deletion of entire list;
- * xfs_iext_irec_remove() updates extent offsets.
- */
- if (ext_diff == erp->er_extcount) {
- xfs_iext_irec_remove(ifp, erp_idx);
- ext_cnt -= ext_diff;
- nex1 = 0;
- if (ext_cnt) {
- ASSERT(erp_idx < ifp->if_real_bytes /
- XFS_IEXT_BUFSZ);
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- nex1 = 0;
- continue;
- } else {
- break;
- }
- }
- /* Move extents up (if needed) */
- if (nex2) {
- memmove(&erp->er_extbuf[nex1],
- &erp->er_extbuf[nex1 + ext_diff],
- nex2 * sizeof(xfs_bmbt_rec_t));
- }
- /* Zero out rest of page */
- memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ -
- ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t))));
- /* Update remaining counters */
- erp->er_extcount -= ext_diff;
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff);
- ext_cnt -= ext_diff;
- nex1 = 0;
- erp_idx++;
- erp++;
- }
- ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t);
- xfs_iext_irec_compact(ifp);
-}
-
-/*
- * Create, destroy, or resize a linear (direct) block of extents.
- */
-void
-xfs_iext_realloc_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* new size of extents */
-{
- int rnew_size; /* real new size of extents */
-
- rnew_size = new_size;
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) ||
- ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) &&
- (new_size != ifp->if_real_bytes)));
-
- /* Free extent records */
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- }
- /* Resize direct extent list and zero any new bytes */
- else if (ifp->if_real_bytes) {
- /* Check if extents will fit inside the inode */
- if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) {
- xfs_iext_direct_to_inline(ifp, new_size /
- (uint)sizeof(xfs_bmbt_rec_t));
- ifp->if_bytes = new_size;
- return;
- }
- if (!is_power_of_2(new_size)){
- rnew_size = roundup_pow_of_two(new_size);
- }
- if (rnew_size != ifp->if_real_bytes) {
- ifp->if_u1.if_extents =
- kmem_realloc(ifp->if_u1.if_extents,
- rnew_size,
- ifp->if_real_bytes, KM_NOFS);
- }
- if (rnew_size > ifp->if_real_bytes) {
- memset(&ifp->if_u1.if_extents[ifp->if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t)], 0,
- rnew_size - ifp->if_real_bytes);
- }
- }
- /*
- * Switch from the inline extent buffer to a direct
- * extent list. Be sure to include the inline extent
- * bytes in new_size.
- */
- else {
- new_size += ifp->if_bytes;
- if (!is_power_of_2(new_size)) {
- rnew_size = roundup_pow_of_two(new_size);
- }
- xfs_iext_inline_to_direct(ifp, rnew_size);
- }
- ifp->if_real_bytes = rnew_size;
- ifp->if_bytes = new_size;
-}
-
-/*
- * Switch from linear (direct) extent records to inline buffer.
- */
-void
-xfs_iext_direct_to_inline(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t nextents) /* number of extents in file */
-{
- ASSERT(ifp->if_flags & XFS_IFEXTENTS);
- ASSERT(nextents <= XFS_INLINE_EXTS);
- /*
- * The inline buffer was zeroed when we switched
- * from inline to direct extent allocation mode,
- * so we don't need to clear it here.
- */
- memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
- nextents * sizeof(xfs_bmbt_rec_t));
- kmem_free(ifp->if_u1.if_extents);
- ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
- ifp->if_real_bytes = 0;
-}
-
-/*
- * Switch from inline buffer to linear (direct) extent records.
- * new_size should already be rounded up to the next power of 2
- * by the caller (when appropriate), so use new_size as it is.
- * However, since new_size may be rounded up, we can't update
- * if_bytes here. It is the caller's responsibility to update
- * if_bytes upon return.
- */
-void
-xfs_iext_inline_to_direct(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* number of extents in file */
-{
- ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS);
- memset(ifp->if_u1.if_extents, 0, new_size);
- if (ifp->if_bytes) {
- memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
- ifp->if_bytes);
- memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
- sizeof(xfs_bmbt_rec_t));
- }
- ifp->if_real_bytes = new_size;
-}
-
-/*
- * Resize an extent indirection array to new_size bytes.
- */
-STATIC void
-xfs_iext_realloc_indirect(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int new_size) /* new indirection array size */
-{
- int nlists; /* number of irec's (ex lists) */
- int size; /* current indirection array size */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- size = nlists * sizeof(xfs_ext_irec_t);
- ASSERT(ifp->if_real_bytes);
- ASSERT((new_size >= 0) && (new_size != size));
- if (new_size == 0) {
- xfs_iext_destroy(ifp);
- } else {
- ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
- kmem_realloc(ifp->if_u1.if_ext_irec,
- new_size, size, KM_NOFS);
- }
-}
-
-/*
- * Switch from indirection array to linear (direct) extent allocations.
- */
-STATIC void
-xfs_iext_indirect_to_direct(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_bmbt_rec_host_t *ep; /* extent record pointer */
- xfs_extnum_t nextents; /* number of extents in file */
- int size; /* size of file extents */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(nextents <= XFS_LINEAR_EXTS);
- size = nextents * sizeof(xfs_bmbt_rec_t);
-
- xfs_iext_irec_compact_pages(ifp);
- ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
-
- ep = ifp->if_u1.if_ext_irec->er_extbuf;
- kmem_free(ifp->if_u1.if_ext_irec);
- ifp->if_flags &= ~XFS_IFEXTIREC;
- ifp->if_u1.if_extents = ep;
- ifp->if_bytes = size;
- if (nextents < XFS_LINEAR_EXTS) {
- xfs_iext_realloc_direct(ifp, size);
- }
-}
-
-/*
- * Free incore file extents.
- */
-void
-xfs_iext_destroy(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- if (ifp->if_flags & XFS_IFEXTIREC) {
- int erp_idx;
- int nlists;
-
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) {
- xfs_iext_irec_remove(ifp, erp_idx);
- }
- ifp->if_flags &= ~XFS_IFEXTIREC;
- } else if (ifp->if_real_bytes) {
- kmem_free(ifp->if_u1.if_extents);
- } else if (ifp->if_bytes) {
- memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
- sizeof(xfs_bmbt_rec_t));
- }
- ifp->if_u1.if_extents = NULL;
- ifp->if_real_bytes = 0;
- ifp->if_bytes = 0;
-}
-
-/*
- * Return a pointer to the extent record for file system block bno.
- */
-xfs_bmbt_rec_host_t * /* pointer to found extent record */
-xfs_iext_bno_to_ext(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number to search for */
- xfs_extnum_t *idxp) /* index of target extent */
-{
- xfs_bmbt_rec_host_t *base; /* pointer to first extent */
- xfs_filblks_t blockcount = 0; /* number of blocks in extent */
- xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */
- xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
- int high; /* upper boundary in search */
- xfs_extnum_t idx = 0; /* index of target extent */
- int low; /* lower boundary in search */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_fileoff_t startoff = 0; /* start offset of extent */
-
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
- *idxp = 0;
- return NULL;
- }
- low = 0;
- if (ifp->if_flags & XFS_IFEXTIREC) {
- /* Find target extent list */
- int erp_idx = 0;
- erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
- base = erp->er_extbuf;
- high = erp->er_extcount - 1;
- } else {
- base = ifp->if_u1.if_extents;
- high = nextents - 1;
- }
- /* Binary search extent records */
- while (low <= high) {
- idx = (low + high) >> 1;
- ep = base + idx;
- startoff = xfs_bmbt_get_startoff(ep);
- blockcount = xfs_bmbt_get_blockcount(ep);
- if (bno < startoff) {
- high = idx - 1;
- } else if (bno >= startoff + blockcount) {
- low = idx + 1;
- } else {
- /* Convert back to file-based extent index */
- if (ifp->if_flags & XFS_IFEXTIREC) {
- idx += erp->er_extoff;
- }
- *idxp = idx;
- return ep;
- }
- }
- /* Convert back to file-based extent index */
- if (ifp->if_flags & XFS_IFEXTIREC) {
- idx += erp->er_extoff;
- }
- if (bno >= startoff + blockcount) {
- if (++idx == nextents) {
- ep = NULL;
- } else {
- ep = xfs_iext_get_ext(ifp, idx);
- }
- }
- *idxp = idx;
- return ep;
-}
-
-/*
- * Return a pointer to the indirection array entry containing the
- * extent record for filesystem block bno. Store the index of the
- * target irec in *erp_idxp.
- */
-xfs_ext_irec_t * /* pointer to found extent record */
-xfs_iext_bno_to_irec(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number to search for */
- int *erp_idxp) /* irec index of target ext list */
-{
- xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
- xfs_ext_irec_t *erp_next; /* next indirection array entry */
- int erp_idx; /* indirection array index */
- int nlists; /* number of extent irec's (lists) */
- int high; /* binary search upper limit */
- int low; /* binary search lower limit */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp_idx = 0;
- low = 0;
- high = nlists - 1;
- while (low <= high) {
- erp_idx = (low + high) >> 1;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL;
- if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) {
- high = erp_idx - 1;
- } else if (erp_next && bno >=
- xfs_bmbt_get_startoff(erp_next->er_extbuf)) {
- low = erp_idx + 1;
- } else {
- break;
- }
- }
- *erp_idxp = erp_idx;
- return erp;
-}
-
-/*
- * Return a pointer to the indirection array entry containing the
- * extent record at file extent index *idxp. Store the index of the
- * target irec in *erp_idxp and store the page index of the target
- * extent record in *idxp.
- */
-xfs_ext_irec_t *
-xfs_iext_idx_to_irec(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_extnum_t *idxp, /* extent index (file -> page) */
- int *erp_idxp, /* pointer to target irec */
- int realloc) /* new bytes were just added */
-{
- xfs_ext_irec_t *prev; /* pointer to previous irec */
- xfs_ext_irec_t *erp = NULL; /* pointer to current irec */
- int erp_idx; /* indirection array index */
- int nlists; /* number of irec's (ex lists) */
- int high; /* binary search upper limit */
- int low; /* binary search lower limit */
- xfs_extnum_t page_idx = *idxp; /* extent index in target list */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- ASSERT(page_idx >= 0);
- ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
- ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
-
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp_idx = 0;
- low = 0;
- high = nlists - 1;
-
- /* Binary search extent irec's */
- while (low <= high) {
- erp_idx = (low + high) >> 1;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- prev = erp_idx > 0 ? erp - 1 : NULL;
- if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff &&
- realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) {
- high = erp_idx - 1;
- } else if (page_idx > erp->er_extoff + erp->er_extcount ||
- (page_idx == erp->er_extoff + erp->er_extcount &&
- !realloc)) {
- low = erp_idx + 1;
- } else if (page_idx == erp->er_extoff + erp->er_extcount &&
- erp->er_extcount == XFS_LINEAR_EXTS) {
- ASSERT(realloc);
- page_idx = 0;
- erp_idx++;
- erp = erp_idx < nlists ? erp + 1 : NULL;
- break;
- } else {
- page_idx -= erp->er_extoff;
- break;
- }
- }
- *idxp = page_idx;
- *erp_idxp = erp_idx;
- return(erp);
-}
-
-/*
- * Allocate and initialize an indirection array once the space needed
- * for incore extents increases above XFS_IEXT_BUFSZ.
- */
-void
-xfs_iext_irec_init(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- xfs_extnum_t nextents; /* number of extents in file */
-
- ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- ASSERT(nextents <= XFS_LINEAR_EXTS);
-
- erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
-
- if (nextents == 0) {
- ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
- } else if (!ifp->if_real_bytes) {
- xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
- } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
- xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ);
- }
- erp->er_extbuf = ifp->if_u1.if_extents;
- erp->er_extcount = nextents;
- erp->er_extoff = 0;
-
- ifp->if_flags |= XFS_IFEXTIREC;
- ifp->if_real_bytes = XFS_IEXT_BUFSZ;
- ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t);
- ifp->if_u1.if_ext_irec = erp;
-
- return;
-}
-
-/*
- * Allocate and initialize a new entry in the indirection array.
- */
-xfs_ext_irec_t *
-xfs_iext_irec_new(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx) /* index for new irec */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
- /* Resize indirection array */
- xfs_iext_realloc_indirect(ifp, ++nlists *
- sizeof(xfs_ext_irec_t));
- /*
- * Move records down in the array so the
- * new page can use erp_idx.
- */
- erp = ifp->if_u1.if_ext_irec;
- for (i = nlists - 1; i > erp_idx; i--) {
- memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t));
- }
- ASSERT(i == erp_idx);
-
- /* Initialize new extent record */
- erp = ifp->if_u1.if_ext_irec;
- erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
- ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
- memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
- erp[erp_idx].er_extcount = 0;
- erp[erp_idx].er_extoff = erp_idx > 0 ?
- erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0;
- return (&erp[erp_idx]);
-}
-
-/*
- * Remove a record from the indirection array.
- */
-void
-xfs_iext_irec_remove(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx) /* irec index to remove */
-{
- xfs_ext_irec_t *erp; /* indirection array pointer */
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- if (erp->er_extbuf) {
- xfs_iext_irec_update_extoffs(ifp, erp_idx + 1,
- -erp->er_extcount);
- kmem_free(erp->er_extbuf);
- }
- /* Compact extent records */
- erp = ifp->if_u1.if_ext_irec;
- for (i = erp_idx; i < nlists - 1; i++) {
- memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t));
- }
- /*
- * Manually free the last extent record from the indirection
- * array. A call to xfs_iext_realloc_indirect() with a size
- * of zero would result in a call to xfs_iext_destroy() which
- * would in turn call this function again, creating a nasty
- * infinite loop.
- */
- if (--nlists) {
- xfs_iext_realloc_indirect(ifp,
- nlists * sizeof(xfs_ext_irec_t));
- } else {
- kmem_free(ifp->if_u1.if_ext_irec);
- }
- ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
-}
-
-/*
- * This is called to clean up large amounts of unused memory allocated
- * by the indirection array. Before compacting anything though, verify
- * that the indirection array is still needed and switch back to the
- * linear extent list (or even the inline buffer) if possible. The
- * compaction policy is as follows:
- *
- * Full Compaction: Extents fit into a single page (or inline buffer)
- * Partial Compaction: Extents occupy less than 50% of allocated space
- * No Compaction: Extents occupy at least 50% of allocated space
- */
-void
-xfs_iext_irec_compact(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_extnum_t nextents; /* number of extents in file */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
-
- if (nextents == 0) {
- xfs_iext_destroy(ifp);
- } else if (nextents <= XFS_INLINE_EXTS) {
- xfs_iext_indirect_to_direct(ifp);
- xfs_iext_direct_to_inline(ifp, nextents);
- } else if (nextents <= XFS_LINEAR_EXTS) {
- xfs_iext_indirect_to_direct(ifp);
- } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
- xfs_iext_irec_compact_pages(ifp);
- }
-}
-
-/*
- * Combine extents from neighboring extent pages.
- */
-void
-xfs_iext_irec_compact_pages(
- xfs_ifork_t *ifp) /* inode fork pointer */
-{
- xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */
- int erp_idx = 0; /* indirection array index */
- int nlists; /* number of irec's (ex lists) */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- while (erp_idx < nlists - 1) {
- erp = &ifp->if_u1.if_ext_irec[erp_idx];
- erp_next = erp + 1;
- if (erp_next->er_extcount <=
- (XFS_LINEAR_EXTS - erp->er_extcount)) {
- memcpy(&erp->er_extbuf[erp->er_extcount],
- erp_next->er_extbuf, erp_next->er_extcount *
- sizeof(xfs_bmbt_rec_t));
- erp->er_extcount += erp_next->er_extcount;
- /*
- * Free page before removing extent record
- * so er_extoffs don't get modified in
- * xfs_iext_irec_remove.
- */
- kmem_free(erp_next->er_extbuf);
- erp_next->er_extbuf = NULL;
- xfs_iext_irec_remove(ifp, erp_idx + 1);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- } else {
- erp_idx++;
- }
- }
-}
-
-/*
- * This is called to update the er_extoff field in the indirection
- * array when extents have been added or removed from one of the
- * extent lists. erp_idx contains the irec index to begin updating
- * at and ext_diff contains the number of extents that were added
- * or removed.
- */
-void
-xfs_iext_irec_update_extoffs(
- xfs_ifork_t *ifp, /* inode fork pointer */
- int erp_idx, /* irec index to update */
- int ext_diff) /* number of new extents */
-{
- int i; /* loop counter */
- int nlists; /* number of irec's (ex lists */
-
- ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- for (i = erp_idx; i < nlists; i++) {
- ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
- }
-}
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
new file mode 100644
index 0000000..1c006f9
--- /dev/null
+++ b/libxfs/xfs_inode_fork.c
@@ -0,0 +1,1890 @@
+/*
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <xfs.h>
+
+kmem_zone_t *xfs_ifork_zone;
+
+STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
+STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
+STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
+
+#ifdef DEBUG
+/*
+ * Make sure that the extents in the given memory buffer
+ * are valid.
+ */
+void
+xfs_validate_extents(
+ xfs_ifork_t *ifp,
+ int nrecs,
+ xfs_exntfmt_t fmt)
+{
+ xfs_bmbt_irec_t irec;
+ xfs_bmbt_rec_host_t rec;
+ int i;
+
+ for (i = 0; i < nrecs; i++) {
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
+ rec.l0 = get_unaligned(&ep->l0);
+ rec.l1 = get_unaligned(&ep->l1);
+ xfs_bmbt_get_all(&rec, &irec);
+ if (fmt == XFS_EXTFMT_NOSTATE)
+ ASSERT(irec.br_state == XFS_EXT_NORM);
+ }
+}
+#else /* DEBUG */
+#define xfs_validate_extents(ifp, nrecs, fmt)
+#endif /* DEBUG */
+
+
+/*
+ * Move inode type and inode format specific information from the
+ * on-disk inode to the in-core inode. For fifos, devs, and sockets
+ * this means set if_rdev to the proper value. For files, directories,
+ * and symlinks this means to bring in the in-line data or extent
+ * pointers. For a file in B-tree format, only the root is immediately
+ * brought in-core. The rest will be in-lined in if_extents when it
+ * is first referenced (see xfs_iread_extents()).
+ */
+int
+xfs_iformat_fork(
+ xfs_inode_t *ip,
+ xfs_dinode_t *dip)
+{
+ xfs_attr_shortform_t *atp;
+ int size;
+ int error = 0;
+ xfs_fsize_t di_size;
+
+ if (unlikely(be32_to_cpu(dip->di_nextents) +
+ be16_to_cpu(dip->di_anextents) >
+ be64_to_cpu(dip->di_nblocks))) {
+ xfs_warn(ip->i_mount,
+ "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
+ (unsigned long long)ip->i_ino,
+ (int)(be32_to_cpu(dip->di_nextents) +
+ be16_to_cpu(dip->di_anextents)),
+ (unsigned long long)
+ be64_to_cpu(dip->di_nblocks));
+ XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) {
+ xfs_warn(ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.",
+ (unsigned long long)ip->i_ino,
+ dip->di_forkoff);
+ XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
+ !ip->i_mount->m_rtdev_targp)) {
+ xfs_warn(ip->i_mount,
+ "corrupt dinode %Lu, has realtime flag set.",
+ ip->i_ino);
+ XFS_CORRUPTION_ERROR("xfs_iformat(realtime)",
+ XFS_ERRLEVEL_LOW, ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ switch (ip->i_d.di_mode & S_IFMT) {
+ case S_IFIFO:
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFSOCK:
+ if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) {
+ XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ ip->i_d.di_size = 0;
+ ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip);
+ break;
+
+ case S_IFREG:
+ case S_IFLNK:
+ case S_IFDIR:
+ switch (dip->di_format) {
+ case XFS_DINODE_FMT_LOCAL:
+ /*
+ * no local regular files yet
+ */
+ if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) {
+ xfs_warn(ip->i_mount,
+ "corrupt inode %Lu (local format for regular file).",
+ (unsigned long long) ip->i_ino);
+ XFS_CORRUPTION_ERROR("xfs_iformat(4)",
+ XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ di_size = be64_to_cpu(dip->di_size);
+ if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
+ xfs_warn(ip->i_mount,
+ "corrupt inode %Lu (bad size %Ld for local inode).",
+ (unsigned long long) ip->i_ino,
+ (long long) di_size);
+ XFS_CORRUPTION_ERROR("xfs_iformat(5)",
+ XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ size = (int)di_size;
+ error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
+ break;
+ case XFS_DINODE_FMT_EXTENTS:
+ error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
+ break;
+ case XFS_DINODE_FMT_BTREE:
+ error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
+ break;
+ default:
+ XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
+ ip->i_mount);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ break;
+
+ default:
+ XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ if (error) {
+ return error;
+ }
+ if (!XFS_DFORK_Q(dip))
+ return 0;
+
+ ASSERT(ip->i_afp == NULL);
+ ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS);
+
+ switch (dip->di_aformat) {
+ case XFS_DINODE_FMT_LOCAL:
+ atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
+ size = be16_to_cpu(atp->hdr.totsize);
+
+ if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) {
+ xfs_warn(ip->i_mount,
+ "corrupt inode %Lu (bad attr fork size %Ld).",
+ (unsigned long long) ip->i_ino,
+ (long long) size);
+ XFS_CORRUPTION_ERROR("xfs_iformat(8)",
+ XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
+ break;
+ case XFS_DINODE_FMT_EXTENTS:
+ error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
+ break;
+ case XFS_DINODE_FMT_BTREE:
+ error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
+ break;
+ default:
+ error = XFS_ERROR(EFSCORRUPTED);
+ break;
+ }
+ if (error) {
+ kmem_zone_free(xfs_ifork_zone, ip->i_afp);
+ ip->i_afp = NULL;
+ xfs_idestroy_fork(ip, XFS_DATA_FORK);
+ }
+ return error;
+}
+
+/*
+ * The file is in-lined in the on-disk inode.
+ * If it fits into if_inline_data, then copy
+ * it there, otherwise allocate a buffer for it
+ * and copy the data there. Either way, set
+ * if_data to point at the data.
+ * If we allocate a buffer for the data, make
+ * sure that its size is a multiple of 4 and
+ * record the real size in i_real_bytes.
+ */
+STATIC int
+xfs_iformat_local(
+ xfs_inode_t *ip,
+ xfs_dinode_t *dip,
+ int whichfork,
+ int size)
+{
+ xfs_ifork_t *ifp;
+ int real_size;
+
+ /*
+ * If the size is unreasonable, then something
+ * is wrong and we just bail out rather than crash in
+ * kmem_alloc() or memcpy() below.
+ */
+ if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
+ xfs_warn(ip->i_mount,
+ "corrupt inode %Lu (bad size %d for local fork, size = %d).",
+ (unsigned long long) ip->i_ino, size,
+ XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
+ XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ real_size = 0;
+ if (size == 0)
+ ifp->if_u1.if_data = NULL;
+ else if (size <= sizeof(ifp->if_u2.if_inline_data))
+ ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
+ else {
+ real_size = roundup(size, 4);
+ ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
+ }
+ ifp->if_bytes = size;
+ ifp->if_real_bytes = real_size;
+ if (size)
+ memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
+ ifp->if_flags &= ~XFS_IFEXTENTS;
+ ifp->if_flags |= XFS_IFINLINE;
+ return 0;
+}
+
+/*
+ * The file consists of a set of extents all
+ * of which fit into the on-disk inode.
+ * If there are few enough extents to fit into
+ * the if_inline_ext, then copy them there.
+ * Otherwise allocate a buffer for them and copy
+ * them into it. Either way, set if_extents
+ * to point at the extents.
+ */
+STATIC int
+xfs_iformat_extents(
+ xfs_inode_t *ip,
+ xfs_dinode_t *dip,
+ int whichfork)
+{
+ xfs_bmbt_rec_t *dp;
+ xfs_ifork_t *ifp;
+ int nex;
+ int size;
+ int i;
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ size = nex * (uint)sizeof(xfs_bmbt_rec_t);
+
+ /*
+ * If the number of extents is unreasonable, then something
+ * is wrong and we just bail out rather than crash in
+ * kmem_alloc() or memcpy() below.
+ */
+ if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
+ xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
+ (unsigned long long) ip->i_ino, nex);
+ XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
+ ip->i_mount, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ ifp->if_real_bytes = 0;
+ if (nex == 0)
+ ifp->if_u1.if_extents = NULL;
+ else if (nex <= XFS_INLINE_EXTS)
+ ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
+ else
+ xfs_iext_add(ifp, 0, nex);
+
+ ifp->if_bytes = size;
+ if (size) {
+ dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
+ xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
+ for (i = 0; i < nex; i++, dp++) {
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
+ ep->l0 = get_unaligned_be64(&dp->l0);
+ ep->l1 = get_unaligned_be64(&dp->l1);
+ }
+ XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
+ if (whichfork != XFS_DATA_FORK ||
+ XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
+ if (unlikely(xfs_check_nostate_extents(
+ ifp, 0, nex))) {
+ XFS_ERROR_REPORT("xfs_iformat_extents(2)",
+ XFS_ERRLEVEL_LOW,
+ ip->i_mount);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ }
+ ifp->if_flags |= XFS_IFEXTENTS;
+ return 0;
+}
+
+/*
+ * The file has too many extents to fit into
+ * the inode, so they are in B-tree format.
+ * Allocate a buffer for the root of the B-tree
+ * and copy the root into it. The i_extents
+ * field will remain NULL until all of the
+ * extents are read in (when they are needed).
+ */
+STATIC int
+xfs_iformat_btree(
+ xfs_inode_t *ip,
+ xfs_dinode_t *dip,
+ int whichfork)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ xfs_bmdr_block_t *dfp;
+ xfs_ifork_t *ifp;
+ /* REFERENCED */
+ int nrecs;
+ int size;
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
+ size = XFS_BMAP_BROOT_SPACE(mp, dfp);
+ nrecs = be16_to_cpu(dfp->bb_numrecs);
+
+ /*
+ * blow out if -- fork has less extents than can fit in
+ * fork (fork shouldn't be a btree format), root btree
+ * block has more records than can fit into the fork,
+ * or the number of extents is greater than the number of
+ * blocks.
+ */
+ if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <=
+ XFS_IFORK_MAXEXT(ip, whichfork) ||
+ XFS_BMDR_SPACE_CALC(nrecs) >
+ XFS_DFORK_SIZE(dip, mp, whichfork) ||
+ XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
+ xfs_warn(mp, "corrupt inode %Lu (btree).",
+ (unsigned long long) ip->i_ino);
+ XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
+ mp, dip);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ ifp->if_broot_bytes = size;
+ ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS);
+ ASSERT(ifp->if_broot != NULL);
+ /*
+ * Copy and convert from the on-disk structure
+ * to the in-memory structure.
+ */
+ xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
+ ifp->if_broot, size);
+ ifp->if_flags &= ~XFS_IFEXTENTS;
+ ifp->if_flags |= XFS_IFBROOT;
+
+ return 0;
+}
+
+/*
+ * Read in extents from a btree-format inode.
+ * Allocate and fill in if_extents. Real work is done in xfs_bmap.c.
+ */
+int
+xfs_iread_extents(
+ xfs_trans_t *tp,
+ xfs_inode_t *ip,
+ int whichfork)
+{
+ int error;
+ xfs_ifork_t *ifp;
+ xfs_extnum_t nextents;
+
+ if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
+ XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
+ ip->i_mount);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+
+ /*
+ * We know that the size is valid (it's checked in iformat_btree)
+ */
+ ifp->if_bytes = ifp->if_real_bytes = 0;
+ ifp->if_flags |= XFS_IFEXTENTS;
+ xfs_iext_add(ifp, 0, nextents);
+ error = xfs_bmap_read_extents(tp, ip, whichfork);
+ if (error) {
+ xfs_iext_destroy(ifp);
+ ifp->if_flags &= ~XFS_IFEXTENTS;
+ return error;
+ }
+ xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
+ return 0;
+}
+/*
+ * Reallocate the space for if_broot based on the number of records
+ * being added or deleted as indicated in rec_diff. Move the records
+ * and pointers in if_broot to fit the new size. When shrinking this
+ * will eliminate holes between the records and pointers created by
+ * the caller. When growing this will create holes to be filled in
+ * by the caller.
+ *
+ * The caller must not request to add more records than would fit in
+ * the on-disk inode root. If the if_broot is currently NULL, then
+ * if we adding records one will be allocated. The caller must also
+ * not request that the number of records go below zero, although
+ * it can go to zero.
+ *
+ * ip -- the inode whose if_broot area is changing
+ * ext_diff -- the change in the number of records, positive or negative,
+ * requested for the if_broot array.
+ */
+void
+xfs_iroot_realloc(
+ xfs_inode_t *ip,
+ int rec_diff,
+ int whichfork)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ int cur_max;
+ xfs_ifork_t *ifp;
+ struct xfs_btree_block *new_broot;
+ int new_max;
+ size_t new_size;
+ char *np;
+ char *op;
+
+ /*
+ * Handle the degenerate case quietly.
+ */
+ if (rec_diff == 0) {
+ return;
+ }
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ if (rec_diff > 0) {
+ /*
+ * If there wasn't any memory allocated before, just
+ * allocate it now and get out.
+ */
+ if (ifp->if_broot_bytes == 0) {
+ new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
+ ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
+ ifp->if_broot_bytes = (int)new_size;
+ return;
+ }
+
+ /*
+ * If there is already an existing if_broot, then we need
+ * to realloc() it and shift the pointers to their new
+ * location. The records don't change location because
+ * they are kept butted up against the btree block header.
+ */
+ cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
+ new_max = cur_max + rec_diff;
+ new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
+ ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
+ XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
+ KM_SLEEP | KM_NOFS);
+ op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
+ ifp->if_broot_bytes);
+ np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
+ (int)new_size);
+ ifp->if_broot_bytes = (int)new_size;
+ ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
+ XFS_IFORK_SIZE(ip, whichfork));
+ memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t));
+ return;
+ }
+
+ /*
+ * rec_diff is less than 0. In this case, we are shrinking the
+ * if_broot buffer. It must already exist. If we go to zero
+ * records, just get rid of the root and clear the status bit.
+ */
+ ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
+ cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
+ new_max = cur_max + rec_diff;
+ ASSERT(new_max >= 0);
+ if (new_max > 0)
+ new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
+ else
+ new_size = 0;
+ if (new_size > 0) {
+ new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
+ /*
+ * First copy over the btree block header.
+ */
+ memcpy(new_broot, ifp->if_broot,
+ XFS_BMBT_BLOCK_LEN(ip->i_mount));
+ } else {
+ new_broot = NULL;
+ ifp->if_flags &= ~XFS_IFBROOT;
+ }
+
+ /*
+ * Only copy the records and pointers if there are any.
+ */
+ if (new_max > 0) {
+ /*
+ * First copy the records.
+ */
+ op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
+ np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
+ memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
+
+ /*
+ * Then copy the pointers.
+ */
+ op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
+ ifp->if_broot_bytes);
+ np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
+ (int)new_size);
+ memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
+ }
+ kmem_free(ifp->if_broot);
+ ifp->if_broot = new_broot;
+ ifp->if_broot_bytes = (int)new_size;
+ if (ifp->if_broot)
+ ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
+ XFS_IFORK_SIZE(ip, whichfork));
+ return;
+}
+
+
+/*
+ * This is called when the amount of space needed for if_data
+ * is increased or decreased. The change in size is indicated by
+ * the number of bytes that need to be added or deleted in the
+ * byte_diff parameter.
+ *
+ * If the amount of space needed has decreased below the size of the
+ * inline buffer, then switch to using the inline buffer. Otherwise,
+ * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
+ * to what is needed.
+ *
+ * ip -- the inode whose if_data area is changing
+ * byte_diff -- the change in the number of bytes, positive or negative,
+ * requested for the if_data array.
+ */
+void
+xfs_idata_realloc(
+ xfs_inode_t *ip,
+ int byte_diff,
+ int whichfork)
+{
+ xfs_ifork_t *ifp;
+ int new_size;
+ int real_size;
+
+ if (byte_diff == 0) {
+ return;
+ }
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ new_size = (int)ifp->if_bytes + byte_diff;
+ ASSERT(new_size >= 0);
+
+ if (new_size == 0) {
+ if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
+ kmem_free(ifp->if_u1.if_data);
+ }
+ ifp->if_u1.if_data = NULL;
+ real_size = 0;
+ } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) {
+ /*
+ * If the valid extents/data can fit in if_inline_ext/data,
+ * copy them from the malloc'd vector and free it.
+ */
+ if (ifp->if_u1.if_data == NULL) {
+ ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
+ } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
+ ASSERT(ifp->if_real_bytes != 0);
+ memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data,
+ new_size);
+ kmem_free(ifp->if_u1.if_data);
+ ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
+ }
+ real_size = 0;
+ } else {
+ /*
+ * Stuck with malloc/realloc.
+ * For inline data, the underlying buffer must be
+ * a multiple of 4 bytes in size so that it can be
+ * logged and stay on word boundaries. We enforce
+ * that here.
+ */
+ real_size = roundup(new_size, 4);
+ if (ifp->if_u1.if_data == NULL) {
+ ASSERT(ifp->if_real_bytes == 0);
+ ifp->if_u1.if_data = kmem_alloc(real_size,
+ KM_SLEEP | KM_NOFS);
+ } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
+ /*
+ * Only do the realloc if the underlying size
+ * is really changing.
+ */
+ if (ifp->if_real_bytes != real_size) {
+ ifp->if_u1.if_data =
+ kmem_realloc(ifp->if_u1.if_data,
+ real_size,
+ ifp->if_real_bytes,
+ KM_SLEEP | KM_NOFS);
+ }
+ } else {
+ ASSERT(ifp->if_real_bytes == 0);
+ ifp->if_u1.if_data = kmem_alloc(real_size,
+ KM_SLEEP | KM_NOFS);
+ memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data,
+ ifp->if_bytes);
+ }
+ }
+ ifp->if_real_bytes = real_size;
+ ifp->if_bytes = new_size;
+ ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
+}
+
+void
+xfs_idestroy_fork(
+ xfs_inode_t *ip,
+ int whichfork)
+{
+ xfs_ifork_t *ifp;
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ if (ifp->if_broot != NULL) {
+ kmem_free(ifp->if_broot);
+ ifp->if_broot = NULL;
+ }
+
+ /*
+ * If the format is local, then we can't have an extents
+ * array so just look for an inline data array. If we're
+ * not local then we may or may not have an extents list,
+ * so check and free it up if we do.
+ */
+ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
+ if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) &&
+ (ifp->if_u1.if_data != NULL)) {
+ ASSERT(ifp->if_real_bytes != 0);
+ kmem_free(ifp->if_u1.if_data);
+ ifp->if_u1.if_data = NULL;
+ ifp->if_real_bytes = 0;
+ }
+ } else if ((ifp->if_flags & XFS_IFEXTENTS) &&
+ ((ifp->if_flags & XFS_IFEXTIREC) ||
+ ((ifp->if_u1.if_extents != NULL) &&
+ (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) {
+ ASSERT(ifp->if_real_bytes != 0);
+ xfs_iext_destroy(ifp);
+ }
+ ASSERT(ifp->if_u1.if_extents == NULL ||
+ ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext);
+ ASSERT(ifp->if_real_bytes == 0);
+ if (whichfork == XFS_ATTR_FORK) {
+ kmem_zone_free(xfs_ifork_zone, ip->i_afp);
+ ip->i_afp = NULL;
+ }
+}
+
+/*
+ * xfs_iextents_copy()
+ *
+ * This is called to copy the REAL extents (as opposed to the delayed
+ * allocation extents) from the inode into the given buffer. It
+ * returns the number of bytes copied into the buffer.
+ *
+ * If there are no delayed allocation extents, then we can just
+ * memcpy() the extents into the buffer. Otherwise, we need to
+ * examine each extent in turn and skip those which are delayed.
+ */
+int
+xfs_iextents_copy(
+ xfs_inode_t *ip,
+ xfs_bmbt_rec_t *dp,
+ int whichfork)
+{
+ int copied;
+ int i;
+ xfs_ifork_t *ifp;
+ int nrecs;
+ xfs_fsblock_t start_block;
+
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
+ ASSERT(ifp->if_bytes > 0);
+
+ nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
+ ASSERT(nrecs > 0);
+
+ /*
+ * There are some delayed allocation extents in the
+ * inode, so copy the extents one at a time and skip
+ * the delayed ones. There must be at least one
+ * non-delayed extent.
+ */
+ copied = 0;
+ for (i = 0; i < nrecs; i++) {
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
+ start_block = xfs_bmbt_get_startblock(ep);
+ if (isnullstartblock(start_block)) {
+ /*
+ * It's a delayed allocation extent, so skip it.
+ */
+ continue;
+ }
+
+ /* Translate to on disk format */
+ put_unaligned_be64(ep->l0, &dp->l0);
+ put_unaligned_be64(ep->l1, &dp->l1);
+ dp++;
+ copied++;
+ }
+ ASSERT(copied != 0);
+ xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
+
+ return (copied * (uint)sizeof(xfs_bmbt_rec_t));
+}
+
+/*
+ * Each of the following cases stores data into the same region
+ * of the on-disk inode, so only one of them can be valid at
+ * any given time. While it is possible to have conflicting formats
+ * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
+ * in EXTENTS format, this can only happen when the fork has
+ * changed formats after being modified but before being flushed.
+ * In these cases, the format always takes precedence, because the
+ * format indicates the current state of the fork.
+ */
+void
+xfs_iflush_fork(
+ xfs_inode_t *ip,
+ xfs_dinode_t *dip,
+ xfs_inode_log_item_t *iip,
+ int whichfork,
+ xfs_buf_t *bp)
+{
+ char *cp;
+ xfs_ifork_t *ifp;
+ xfs_mount_t *mp;
+ static const short brootflag[2] =
+ { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
+ static const short dataflag[2] =
+ { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
+ static const short extflag[2] =
+ { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
+
+ if (!iip)
+ return;
+ ifp = XFS_IFORK_PTR(ip, whichfork);
+ /*
+ * This can happen if we gave up in iformat in an error path,
+ * for the attribute fork.
+ */
+ if (!ifp) {
+ ASSERT(whichfork == XFS_ATTR_FORK);
+ return;
+ }
+ cp = XFS_DFORK_PTR(dip, whichfork);
+ mp = ip->i_mount;
+ switch (XFS_IFORK_FORMAT(ip, whichfork)) {
+ case XFS_DINODE_FMT_LOCAL:
+ if ((iip->ili_fields & dataflag[whichfork]) &&
+ (ifp->if_bytes > 0)) {
+ ASSERT(ifp->if_u1.if_data != NULL);
+ ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
+ memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
+ }
+ break;
+
+ case XFS_DINODE_FMT_EXTENTS:
+ ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
+ !(iip->ili_fields & extflag[whichfork]));
+ if ((iip->ili_fields & extflag[whichfork]) &&
+ (ifp->if_bytes > 0)) {
+ ASSERT(xfs_iext_get_ext(ifp, 0));
+ ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
+ (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
+ whichfork);
+ }
+ break;
+
+ case XFS_DINODE_FMT_BTREE:
+ if ((iip->ili_fields & brootflag[whichfork]) &&
+ (ifp->if_broot_bytes > 0)) {
+ ASSERT(ifp->if_broot != NULL);
+ ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
+ XFS_IFORK_SIZE(ip, whichfork));
+ xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
+ (xfs_bmdr_block_t *)cp,
+ XFS_DFORK_SIZE(dip, mp, whichfork));
+ }
+ break;
+
+ case XFS_DINODE_FMT_DEV:
+ if (iip->ili_fields & XFS_ILOG_DEV) {
+ ASSERT(whichfork == XFS_DATA_FORK);
+ xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev);
+ }
+ break;
+
+ case XFS_DINODE_FMT_UUID:
+ if (iip->ili_fields & XFS_ILOG_UUID) {
+ ASSERT(whichfork == XFS_DATA_FORK);
+ memcpy(XFS_DFORK_DPTR(dip),
+ &ip->i_df.if_u2.if_uuid,
+ sizeof(uuid_t));
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+/*
+ * Return a pointer to the extent record at file index idx.
+ */
+xfs_bmbt_rec_host_t *
+xfs_iext_get_ext(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t idx) /* index of target extent */
+{
+ ASSERT(idx >= 0);
+ ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
+
+ if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
+ return ifp->if_u1.if_ext_irec->er_extbuf;
+ } else if (ifp->if_flags & XFS_IFEXTIREC) {
+ xfs_ext_irec_t *erp; /* irec pointer */
+ int erp_idx = 0; /* irec index */
+ xfs_extnum_t page_idx = idx; /* ext index in target list */
+
+ erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
+ return &erp->er_extbuf[page_idx];
+ } else if (ifp->if_bytes) {
+ return &ifp->if_u1.if_extents[idx];
+ } else {
+ return NULL;
+ }
+}
+
+/*
+ * Insert new item(s) into the extent records for incore inode
+ * fork 'ifp'. 'count' new items are inserted at index 'idx'.
+ */
+void
+xfs_iext_insert(
+ xfs_inode_t *ip, /* incore inode pointer */
+ xfs_extnum_t idx, /* starting index of new items */
+ xfs_extnum_t count, /* number of inserted items */
+ xfs_bmbt_irec_t *new, /* items to insert */
+ int state) /* type of extent conversion */
+{
+ xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
+ xfs_extnum_t i; /* extent record index */
+
+ trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_);
+
+ ASSERT(ifp->if_flags & XFS_IFEXTENTS);
+ xfs_iext_add(ifp, idx, count);
+ for (i = idx; i < idx + count; i++, new++)
+ xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new);
+}
+
+/*
+ * This is called when the amount of space required for incore file
+ * extents needs to be increased. The ext_diff parameter stores the
+ * number of new extents being added and the idx parameter contains
+ * the extent index where the new extents will be added. If the new
+ * extents are being appended, then we just need to (re)allocate and
+ * initialize the space. Otherwise, if the new extents are being
+ * inserted into the middle of the existing entries, a bit more work
+ * is required to make room for the new extents to be inserted. The
+ * caller is responsible for filling in the new extent entries upon
+ * return.
+ */
+void
+xfs_iext_add(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t idx, /* index to begin adding exts */
+ int ext_diff) /* number of extents to add */
+{
+ int byte_diff; /* new bytes being added */
+ int new_size; /* size of extents after adding */
+ xfs_extnum_t nextents; /* number of extents in file */
+
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ ASSERT((idx >= 0) && (idx <= nextents));
+ byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
+ new_size = ifp->if_bytes + byte_diff;
+ /*
+ * If the new number of extents (nextents + ext_diff)
+ * fits inside the inode, then continue to use the inline
+ * extent buffer.
+ */
+ if (nextents + ext_diff <= XFS_INLINE_EXTS) {
+ if (idx < nextents) {
+ memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff],
+ &ifp->if_u2.if_inline_ext[idx],
+ (nextents - idx) * sizeof(xfs_bmbt_rec_t));
+ memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff);
+ }
+ ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
+ ifp->if_real_bytes = 0;
+ }
+ /*
+ * Otherwise use a linear (direct) extent list.
+ * If the extents are currently inside the inode,
+ * xfs_iext_realloc_direct will switch us from
+ * inline to direct extent allocation mode.
+ */
+ else if (nextents + ext_diff <= XFS_LINEAR_EXTS) {
+ xfs_iext_realloc_direct(ifp, new_size);
+ if (idx < nextents) {
+ memmove(&ifp->if_u1.if_extents[idx + ext_diff],
+ &ifp->if_u1.if_extents[idx],
+ (nextents - idx) * sizeof(xfs_bmbt_rec_t));
+ memset(&ifp->if_u1.if_extents[idx], 0, byte_diff);
+ }
+ }
+ /* Indirection array */
+ else {
+ xfs_ext_irec_t *erp;
+ int erp_idx = 0;
+ int page_idx = idx;
+
+ ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS);
+ if (ifp->if_flags & XFS_IFEXTIREC) {
+ erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1);
+ } else {
+ xfs_iext_irec_init(ifp);
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ erp = ifp->if_u1.if_ext_irec;
+ }
+ /* Extents fit in target extent page */
+ if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) {
+ if (page_idx < erp->er_extcount) {
+ memmove(&erp->er_extbuf[page_idx + ext_diff],
+ &erp->er_extbuf[page_idx],
+ (erp->er_extcount - page_idx) *
+ sizeof(xfs_bmbt_rec_t));
+ memset(&erp->er_extbuf[page_idx], 0, byte_diff);
+ }
+ erp->er_extcount += ext_diff;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
+ }
+ /* Insert a new extent page */
+ else if (erp) {
+ xfs_iext_add_indirect_multi(ifp,
+ erp_idx, page_idx, ext_diff);
+ }
+ /*
+ * If extent(s) are being appended to the last page in
+ * the indirection array and the new extent(s) don't fit
+ * in the page, then erp is NULL and erp_idx is set to
+ * the next index needed in the indirection array.
+ */
+ else {
+ int count = ext_diff;
+
+ while (count) {
+ erp = xfs_iext_irec_new(ifp, erp_idx);
+ erp->er_extcount = count;
+ count -= MIN(count, (int)XFS_LINEAR_EXTS);
+ if (count) {
+ erp_idx++;
+ }
+ }
+ }
+ }
+ ifp->if_bytes = new_size;
+}
+
+/*
+ * This is called when incore extents are being added to the indirection
+ * array and the new extents do not fit in the target extent list. The
+ * erp_idx parameter contains the irec index for the target extent list
+ * in the indirection array, and the idx parameter contains the extent
+ * index within the list. The number of extents being added is stored
+ * in the count parameter.
+ *
+ * |-------| |-------|
+ * | | | | idx - number of extents before idx
+ * | idx | | count |
+ * | | | | count - number of extents being inserted at idx
+ * |-------| |-------|
+ * | count | | nex2 | nex2 - number of extents after idx + count
+ * |-------| |-------|
+ */
+void
+xfs_iext_add_indirect_multi(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int erp_idx, /* target extent irec index */
+ xfs_extnum_t idx, /* index within target list */
+ int count) /* new extents being added */
+{
+ int byte_diff; /* new bytes being added */
+ xfs_ext_irec_t *erp; /* pointer to irec entry */
+ xfs_extnum_t ext_diff; /* number of extents to add */
+ xfs_extnum_t ext_cnt; /* new extents still needed */
+ xfs_extnum_t nex2; /* extents after idx + count */
+ xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */
+ int nlists; /* number of irec's (lists) */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ nex2 = erp->er_extcount - idx;
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+
+ /*
+ * Save second part of target extent list
+ * (all extents past */
+ if (nex2) {
+ byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
+ nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS);
+ memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff);
+ erp->er_extcount -= nex2;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2);
+ memset(&erp->er_extbuf[idx], 0, byte_diff);
+ }
+
+ /*
+ * Add the new extents to the end of the target
+ * list, then allocate new irec record(s) and
+ * extent buffer(s) as needed to store the rest
+ * of the new extents.
+ */
+ ext_cnt = count;
+ ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount);
+ if (ext_diff) {
+ erp->er_extcount += ext_diff;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
+ ext_cnt -= ext_diff;
+ }
+ while (ext_cnt) {
+ erp_idx++;
+ erp = xfs_iext_irec_new(ifp, erp_idx);
+ ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS);
+ erp->er_extcount = ext_diff;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
+ ext_cnt -= ext_diff;
+ }
+
+ /* Add nex2 extents back to indirection array */
+ if (nex2) {
+ xfs_extnum_t ext_avail;
+ int i;
+
+ byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
+ ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
+ i = 0;
+ /*
+ * If nex2 extents fit in the current page, append
+ * nex2_ep after the new extents.
+ */
+ if (nex2 <= ext_avail) {
+ i = erp->er_extcount;
+ }
+ /*
+ * Otherwise, check if space is available in the
+ * next page.
+ */
+ else if ((erp_idx < nlists - 1) &&
+ (nex2 <= (ext_avail = XFS_LINEAR_EXTS -
+ ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) {
+ erp_idx++;
+ erp++;
+ /* Create a hole for nex2 extents */
+ memmove(&erp->er_extbuf[nex2], erp->er_extbuf,
+ erp->er_extcount * sizeof(xfs_bmbt_rec_t));
+ }
+ /*
+ * Final choice, create a new extent page for
+ * nex2 extents.
+ */
+ else {
+ erp_idx++;
+ erp = xfs_iext_irec_new(ifp, erp_idx);
+ }
+ memmove(&erp->er_extbuf[i], nex2_ep, byte_diff);
+ kmem_free(nex2_ep);
+ erp->er_extcount += nex2;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2);
+ }
+}
+
+/*
+ * This is called when the amount of space required for incore file
+ * extents needs to be decreased. The ext_diff parameter stores the
+ * number of extents to be removed and the idx parameter contains
+ * the extent index where the extents will be removed from.
+ *
+ * If the amount of space needed has decreased below the linear
+ * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous
+ * extent array. Otherwise, use kmem_realloc() to adjust the
+ * size to what is needed.
+ */
+void
+xfs_iext_remove(
+ xfs_inode_t *ip, /* incore inode pointer */
+ xfs_extnum_t idx, /* index to begin removing exts */
+ int ext_diff, /* number of extents to remove */
+ int state) /* type of extent conversion */
+{
+ xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
+ xfs_extnum_t nextents; /* number of extents in file */
+ int new_size; /* size of extents after removal */
+
+ trace_xfs_iext_remove(ip, idx, state, _RET_IP_);
+
+ ASSERT(ext_diff > 0);
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
+
+ if (new_size == 0) {
+ xfs_iext_destroy(ifp);
+ } else if (ifp->if_flags & XFS_IFEXTIREC) {
+ xfs_iext_remove_indirect(ifp, idx, ext_diff);
+ } else if (ifp->if_real_bytes) {
+ xfs_iext_remove_direct(ifp, idx, ext_diff);
+ } else {
+ xfs_iext_remove_inline(ifp, idx, ext_diff);
+ }
+ ifp->if_bytes = new_size;
+}
+
+/*
+ * This removes ext_diff extents from the inline buffer, beginning
+ * at extent index idx.
+ */
+void
+xfs_iext_remove_inline(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t idx, /* index to begin removing exts */
+ int ext_diff) /* number of extents to remove */
+{
+ int nextents; /* number of extents in file */
+
+ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
+ ASSERT(idx < XFS_INLINE_EXTS);
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ ASSERT(((nextents - ext_diff) > 0) &&
+ (nextents - ext_diff) < XFS_INLINE_EXTS);
+
+ if (idx + ext_diff < nextents) {
+ memmove(&ifp->if_u2.if_inline_ext[idx],
+ &ifp->if_u2.if_inline_ext[idx + ext_diff],
+ (nextents - (idx + ext_diff)) *
+ sizeof(xfs_bmbt_rec_t));
+ memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff],
+ 0, ext_diff * sizeof(xfs_bmbt_rec_t));
+ } else {
+ memset(&ifp->if_u2.if_inline_ext[idx], 0,
+ ext_diff * sizeof(xfs_bmbt_rec_t));
+ }
+}
+
+/*
+ * This removes ext_diff extents from a linear (direct) extent list,
+ * beginning at extent index idx. If the extents are being removed
+ * from the end of the list (ie. truncate) then we just need to re-
+ * allocate the list to remove the extra space. Otherwise, if the
+ * extents are being removed from the middle of the existing extent
+ * entries, then we first need to move the extent records beginning
+ * at idx + ext_diff up in the list to overwrite the records being
+ * removed, then remove the extra space via kmem_realloc.
+ */
+void
+xfs_iext_remove_direct(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t idx, /* index to begin removing exts */
+ int ext_diff) /* number of extents to remove */
+{
+ xfs_extnum_t nextents; /* number of extents in file */
+ int new_size; /* size of extents after removal */
+
+ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
+ new_size = ifp->if_bytes -
+ (ext_diff * sizeof(xfs_bmbt_rec_t));
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+
+ if (new_size == 0) {
+ xfs_iext_destroy(ifp);
+ return;
+ }
+ /* Move extents up in the list (if needed) */
+ if (idx + ext_diff < nextents) {
+ memmove(&ifp->if_u1.if_extents[idx],
+ &ifp->if_u1.if_extents[idx + ext_diff],
+ (nextents - (idx + ext_diff)) *
+ sizeof(xfs_bmbt_rec_t));
+ }
+ memset(&ifp->if_u1.if_extents[nextents - ext_diff],
+ 0, ext_diff * sizeof(xfs_bmbt_rec_t));
+ /*
+ * Reallocate the direct extent list. If the extents
+ * will fit inside the inode then xfs_iext_realloc_direct
+ * will switch from direct to inline extent allocation
+ * mode for us.
+ */
+ xfs_iext_realloc_direct(ifp, new_size);
+ ifp->if_bytes = new_size;
+}
+
+/*
+ * This is called when incore extents are being removed from the
+ * indirection array and the extents being removed span multiple extent
+ * buffers. The idx parameter contains the file extent index where we
+ * want to begin removing extents, and the count parameter contains
+ * how many extents need to be removed.
+ *
+ * |-------| |-------|
+ * | nex1 | | | nex1 - number of extents before idx
+ * |-------| | count |
+ * | | | | count - number of extents being removed at idx
+ * | count | |-------|
+ * | | | nex2 | nex2 - number of extents after idx + count
+ * |-------| |-------|
+ */
+void
+xfs_iext_remove_indirect(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t idx, /* index to begin removing extents */
+ int count) /* number of extents to remove */
+{
+ xfs_ext_irec_t *erp; /* indirection array pointer */
+ int erp_idx = 0; /* indirection array index */
+ xfs_extnum_t ext_cnt; /* extents left to remove */
+ xfs_extnum_t ext_diff; /* extents to remove in current list */
+ xfs_extnum_t nex1; /* number of extents before idx */
+ xfs_extnum_t nex2; /* extents after idx + count */
+ int page_idx = idx; /* index in target extent list */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
+ ASSERT(erp != NULL);
+ nex1 = page_idx;
+ ext_cnt = count;
+ while (ext_cnt) {
+ nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0);
+ ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1));
+ /*
+ * Check for deletion of entire list;
+ * xfs_iext_irec_remove() updates extent offsets.
+ */
+ if (ext_diff == erp->er_extcount) {
+ xfs_iext_irec_remove(ifp, erp_idx);
+ ext_cnt -= ext_diff;
+ nex1 = 0;
+ if (ext_cnt) {
+ ASSERT(erp_idx < ifp->if_real_bytes /
+ XFS_IEXT_BUFSZ);
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ nex1 = 0;
+ continue;
+ } else {
+ break;
+ }
+ }
+ /* Move extents up (if needed) */
+ if (nex2) {
+ memmove(&erp->er_extbuf[nex1],
+ &erp->er_extbuf[nex1 + ext_diff],
+ nex2 * sizeof(xfs_bmbt_rec_t));
+ }
+ /* Zero out rest of page */
+ memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ -
+ ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t))));
+ /* Update remaining counters */
+ erp->er_extcount -= ext_diff;
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff);
+ ext_cnt -= ext_diff;
+ nex1 = 0;
+ erp_idx++;
+ erp++;
+ }
+ ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t);
+ xfs_iext_irec_compact(ifp);
+}
+
+/*
+ * Create, destroy, or resize a linear (direct) block of extents.
+ */
+void
+xfs_iext_realloc_direct(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int new_size) /* new size of extents */
+{
+ int rnew_size; /* real new size of extents */
+
+ rnew_size = new_size;
+
+ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) ||
+ ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) &&
+ (new_size != ifp->if_real_bytes)));
+
+ /* Free extent records */
+ if (new_size == 0) {
+ xfs_iext_destroy(ifp);
+ }
+ /* Resize direct extent list and zero any new bytes */
+ else if (ifp->if_real_bytes) {
+ /* Check if extents will fit inside the inode */
+ if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) {
+ xfs_iext_direct_to_inline(ifp, new_size /
+ (uint)sizeof(xfs_bmbt_rec_t));
+ ifp->if_bytes = new_size;
+ return;
+ }
+ if (!is_power_of_2(new_size)){
+ rnew_size = roundup_pow_of_two(new_size);
+ }
+ if (rnew_size != ifp->if_real_bytes) {
+ ifp->if_u1.if_extents =
+ kmem_realloc(ifp->if_u1.if_extents,
+ rnew_size,
+ ifp->if_real_bytes, KM_NOFS);
+ }
+ if (rnew_size > ifp->if_real_bytes) {
+ memset(&ifp->if_u1.if_extents[ifp->if_bytes /
+ (uint)sizeof(xfs_bmbt_rec_t)], 0,
+ rnew_size - ifp->if_real_bytes);
+ }
+ }
+ /*
+ * Switch from the inline extent buffer to a direct
+ * extent list. Be sure to include the inline extent
+ * bytes in new_size.
+ */
+ else {
+ new_size += ifp->if_bytes;
+ if (!is_power_of_2(new_size)) {
+ rnew_size = roundup_pow_of_two(new_size);
+ }
+ xfs_iext_inline_to_direct(ifp, rnew_size);
+ }
+ ifp->if_real_bytes = rnew_size;
+ ifp->if_bytes = new_size;
+}
+
+/*
+ * Switch from linear (direct) extent records to inline buffer.
+ */
+void
+xfs_iext_direct_to_inline(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t nextents) /* number of extents in file */
+{
+ ASSERT(ifp->if_flags & XFS_IFEXTENTS);
+ ASSERT(nextents <= XFS_INLINE_EXTS);
+ /*
+ * The inline buffer was zeroed when we switched
+ * from inline to direct extent allocation mode,
+ * so we don't need to clear it here.
+ */
+ memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
+ nextents * sizeof(xfs_bmbt_rec_t));
+ kmem_free(ifp->if_u1.if_extents);
+ ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
+ ifp->if_real_bytes = 0;
+}
+
+/*
+ * Switch from inline buffer to linear (direct) extent records.
+ * new_size should already be rounded up to the next power of 2
+ * by the caller (when appropriate), so use new_size as it is.
+ * However, since new_size may be rounded up, we can't update
+ * if_bytes here. It is the caller's responsibility to update
+ * if_bytes upon return.
+ */
+void
+xfs_iext_inline_to_direct(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int new_size) /* number of extents in file */
+{
+ ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS);
+ memset(ifp->if_u1.if_extents, 0, new_size);
+ if (ifp->if_bytes) {
+ memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
+ ifp->if_bytes);
+ memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
+ sizeof(xfs_bmbt_rec_t));
+ }
+ ifp->if_real_bytes = new_size;
+}
+
+/*
+ * Resize an extent indirection array to new_size bytes.
+ */
+STATIC void
+xfs_iext_realloc_indirect(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int new_size) /* new indirection array size */
+{
+ int nlists; /* number of irec's (ex lists) */
+ int size; /* current indirection array size */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ size = nlists * sizeof(xfs_ext_irec_t);
+ ASSERT(ifp->if_real_bytes);
+ ASSERT((new_size >= 0) && (new_size != size));
+ if (new_size == 0) {
+ xfs_iext_destroy(ifp);
+ } else {
+ ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
+ kmem_realloc(ifp->if_u1.if_ext_irec,
+ new_size, size, KM_NOFS);
+ }
+}
+
+/*
+ * Switch from indirection array to linear (direct) extent allocations.
+ */
+STATIC void
+xfs_iext_indirect_to_direct(
+ xfs_ifork_t *ifp) /* inode fork pointer */
+{
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
+ xfs_extnum_t nextents; /* number of extents in file */
+ int size; /* size of file extents */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ ASSERT(nextents <= XFS_LINEAR_EXTS);
+ size = nextents * sizeof(xfs_bmbt_rec_t);
+
+ xfs_iext_irec_compact_pages(ifp);
+ ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
+
+ ep = ifp->if_u1.if_ext_irec->er_extbuf;
+ kmem_free(ifp->if_u1.if_ext_irec);
+ ifp->if_flags &= ~XFS_IFEXTIREC;
+ ifp->if_u1.if_extents = ep;
+ ifp->if_bytes = size;
+ if (nextents < XFS_LINEAR_EXTS) {
+ xfs_iext_realloc_direct(ifp, size);
+ }
+}
+
+/*
+ * Free incore file extents.
+ */
+void
+xfs_iext_destroy(
+ xfs_ifork_t *ifp) /* inode fork pointer */
+{
+ if (ifp->if_flags & XFS_IFEXTIREC) {
+ int erp_idx;
+ int nlists;
+
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) {
+ xfs_iext_irec_remove(ifp, erp_idx);
+ }
+ ifp->if_flags &= ~XFS_IFEXTIREC;
+ } else if (ifp->if_real_bytes) {
+ kmem_free(ifp->if_u1.if_extents);
+ } else if (ifp->if_bytes) {
+ memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
+ sizeof(xfs_bmbt_rec_t));
+ }
+ ifp->if_u1.if_extents = NULL;
+ ifp->if_real_bytes = 0;
+ ifp->if_bytes = 0;
+}
+
+/*
+ * Return a pointer to the extent record for file system block bno.
+ */
+xfs_bmbt_rec_host_t * /* pointer to found extent record */
+xfs_iext_bno_to_ext(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_fileoff_t bno, /* block number to search for */
+ xfs_extnum_t *idxp) /* index of target extent */
+{
+ xfs_bmbt_rec_host_t *base; /* pointer to first extent */
+ xfs_filblks_t blockcount = 0; /* number of blocks in extent */
+ xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */
+ xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
+ int high; /* upper boundary in search */
+ xfs_extnum_t idx = 0; /* index of target extent */
+ int low; /* lower boundary in search */
+ xfs_extnum_t nextents; /* number of file extents */
+ xfs_fileoff_t startoff = 0; /* start offset of extent */
+
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ if (nextents == 0) {
+ *idxp = 0;
+ return NULL;
+ }
+ low = 0;
+ if (ifp->if_flags & XFS_IFEXTIREC) {
+ /* Find target extent list */
+ int erp_idx = 0;
+ erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
+ base = erp->er_extbuf;
+ high = erp->er_extcount - 1;
+ } else {
+ base = ifp->if_u1.if_extents;
+ high = nextents - 1;
+ }
+ /* Binary search extent records */
+ while (low <= high) {
+ idx = (low + high) >> 1;
+ ep = base + idx;
+ startoff = xfs_bmbt_get_startoff(ep);
+ blockcount = xfs_bmbt_get_blockcount(ep);
+ if (bno < startoff) {
+ high = idx - 1;
+ } else if (bno >= startoff + blockcount) {
+ low = idx + 1;
+ } else {
+ /* Convert back to file-based extent index */
+ if (ifp->if_flags & XFS_IFEXTIREC) {
+ idx += erp->er_extoff;
+ }
+ *idxp = idx;
+ return ep;
+ }
+ }
+ /* Convert back to file-based extent index */
+ if (ifp->if_flags & XFS_IFEXTIREC) {
+ idx += erp->er_extoff;
+ }
+ if (bno >= startoff + blockcount) {
+ if (++idx == nextents) {
+ ep = NULL;
+ } else {
+ ep = xfs_iext_get_ext(ifp, idx);
+ }
+ }
+ *idxp = idx;
+ return ep;
+}
+
+/*
+ * Return a pointer to the indirection array entry containing the
+ * extent record for filesystem block bno. Store the index of the
+ * target irec in *erp_idxp.
+ */
+xfs_ext_irec_t * /* pointer to found extent record */
+xfs_iext_bno_to_irec(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_fileoff_t bno, /* block number to search for */
+ int *erp_idxp) /* irec index of target ext list */
+{
+ xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
+ xfs_ext_irec_t *erp_next; /* next indirection array entry */
+ int erp_idx; /* indirection array index */
+ int nlists; /* number of extent irec's (lists) */
+ int high; /* binary search upper limit */
+ int low; /* binary search lower limit */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ erp_idx = 0;
+ low = 0;
+ high = nlists - 1;
+ while (low <= high) {
+ erp_idx = (low + high) >> 1;
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL;
+ if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) {
+ high = erp_idx - 1;
+ } else if (erp_next && bno >=
+ xfs_bmbt_get_startoff(erp_next->er_extbuf)) {
+ low = erp_idx + 1;
+ } else {
+ break;
+ }
+ }
+ *erp_idxp = erp_idx;
+ return erp;
+}
+
+/*
+ * Return a pointer to the indirection array entry containing the
+ * extent record at file extent index *idxp. Store the index of the
+ * target irec in *erp_idxp and store the page index of the target
+ * extent record in *idxp.
+ */
+xfs_ext_irec_t *
+xfs_iext_idx_to_irec(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ xfs_extnum_t *idxp, /* extent index (file -> page) */
+ int *erp_idxp, /* pointer to target irec */
+ int realloc) /* new bytes were just added */
+{
+ xfs_ext_irec_t *prev; /* pointer to previous irec */
+ xfs_ext_irec_t *erp = NULL; /* pointer to current irec */
+ int erp_idx; /* indirection array index */
+ int nlists; /* number of irec's (ex lists) */
+ int high; /* binary search upper limit */
+ int low; /* binary search lower limit */
+ xfs_extnum_t page_idx = *idxp; /* extent index in target list */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ ASSERT(page_idx >= 0);
+ ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
+ ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
+
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ erp_idx = 0;
+ low = 0;
+ high = nlists - 1;
+
+ /* Binary search extent irec's */
+ while (low <= high) {
+ erp_idx = (low + high) >> 1;
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ prev = erp_idx > 0 ? erp - 1 : NULL;
+ if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff &&
+ realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) {
+ high = erp_idx - 1;
+ } else if (page_idx > erp->er_extoff + erp->er_extcount ||
+ (page_idx == erp->er_extoff + erp->er_extcount &&
+ !realloc)) {
+ low = erp_idx + 1;
+ } else if (page_idx == erp->er_extoff + erp->er_extcount &&
+ erp->er_extcount == XFS_LINEAR_EXTS) {
+ ASSERT(realloc);
+ page_idx = 0;
+ erp_idx++;
+ erp = erp_idx < nlists ? erp + 1 : NULL;
+ break;
+ } else {
+ page_idx -= erp->er_extoff;
+ break;
+ }
+ }
+ *idxp = page_idx;
+ *erp_idxp = erp_idx;
+ return(erp);
+}
+
+/*
+ * Allocate and initialize an indirection array once the space needed
+ * for incore extents increases above XFS_IEXT_BUFSZ.
+ */
+void
+xfs_iext_irec_init(
+ xfs_ifork_t *ifp) /* inode fork pointer */
+{
+ xfs_ext_irec_t *erp; /* indirection array pointer */
+ xfs_extnum_t nextents; /* number of extents in file */
+
+ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ ASSERT(nextents <= XFS_LINEAR_EXTS);
+
+ erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
+
+ if (nextents == 0) {
+ ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
+ } else if (!ifp->if_real_bytes) {
+ xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
+ } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
+ xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ);
+ }
+ erp->er_extbuf = ifp->if_u1.if_extents;
+ erp->er_extcount = nextents;
+ erp->er_extoff = 0;
+
+ ifp->if_flags |= XFS_IFEXTIREC;
+ ifp->if_real_bytes = XFS_IEXT_BUFSZ;
+ ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t);
+ ifp->if_u1.if_ext_irec = erp;
+
+ return;
+}
+
+/*
+ * Allocate and initialize a new entry in the indirection array.
+ */
+xfs_ext_irec_t *
+xfs_iext_irec_new(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int erp_idx) /* index for new irec */
+{
+ xfs_ext_irec_t *erp; /* indirection array pointer */
+ int i; /* loop counter */
+ int nlists; /* number of irec's (ex lists) */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+
+ /* Resize indirection array */
+ xfs_iext_realloc_indirect(ifp, ++nlists *
+ sizeof(xfs_ext_irec_t));
+ /*
+ * Move records down in the array so the
+ * new page can use erp_idx.
+ */
+ erp = ifp->if_u1.if_ext_irec;
+ for (i = nlists - 1; i > erp_idx; i--) {
+ memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t));
+ }
+ ASSERT(i == erp_idx);
+
+ /* Initialize new extent record */
+ erp = ifp->if_u1.if_ext_irec;
+ erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
+ ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
+ memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
+ erp[erp_idx].er_extcount = 0;
+ erp[erp_idx].er_extoff = erp_idx > 0 ?
+ erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0;
+ return (&erp[erp_idx]);
+}
+
+/*
+ * Remove a record from the indirection array.
+ */
+void
+xfs_iext_irec_remove(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int erp_idx) /* irec index to remove */
+{
+ xfs_ext_irec_t *erp; /* indirection array pointer */
+ int i; /* loop counter */
+ int nlists; /* number of irec's (ex lists) */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ if (erp->er_extbuf) {
+ xfs_iext_irec_update_extoffs(ifp, erp_idx + 1,
+ -erp->er_extcount);
+ kmem_free(erp->er_extbuf);
+ }
+ /* Compact extent records */
+ erp = ifp->if_u1.if_ext_irec;
+ for (i = erp_idx; i < nlists - 1; i++) {
+ memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t));
+ }
+ /*
+ * Manually free the last extent record from the indirection
+ * array. A call to xfs_iext_realloc_indirect() with a size
+ * of zero would result in a call to xfs_iext_destroy() which
+ * would in turn call this function again, creating a nasty
+ * infinite loop.
+ */
+ if (--nlists) {
+ xfs_iext_realloc_indirect(ifp,
+ nlists * sizeof(xfs_ext_irec_t));
+ } else {
+ kmem_free(ifp->if_u1.if_ext_irec);
+ }
+ ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
+}
+
+/*
+ * This is called to clean up large amounts of unused memory allocated
+ * by the indirection array. Before compacting anything though, verify
+ * that the indirection array is still needed and switch back to the
+ * linear extent list (or even the inline buffer) if possible. The
+ * compaction policy is as follows:
+ *
+ * Full Compaction: Extents fit into a single page (or inline buffer)
+ * Partial Compaction: Extents occupy less than 50% of allocated space
+ * No Compaction: Extents occupy at least 50% of allocated space
+ */
+void
+xfs_iext_irec_compact(
+ xfs_ifork_t *ifp) /* inode fork pointer */
+{
+ xfs_extnum_t nextents; /* number of extents in file */
+ int nlists; /* number of irec's (ex lists) */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+
+ if (nextents == 0) {
+ xfs_iext_destroy(ifp);
+ } else if (nextents <= XFS_INLINE_EXTS) {
+ xfs_iext_indirect_to_direct(ifp);
+ xfs_iext_direct_to_inline(ifp, nextents);
+ } else if (nextents <= XFS_LINEAR_EXTS) {
+ xfs_iext_indirect_to_direct(ifp);
+ } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
+ xfs_iext_irec_compact_pages(ifp);
+ }
+}
+
+/*
+ * Combine extents from neighboring extent pages.
+ */
+void
+xfs_iext_irec_compact_pages(
+ xfs_ifork_t *ifp) /* inode fork pointer */
+{
+ xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */
+ int erp_idx = 0; /* indirection array index */
+ int nlists; /* number of irec's (ex lists) */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ while (erp_idx < nlists - 1) {
+ erp = &ifp->if_u1.if_ext_irec[erp_idx];
+ erp_next = erp + 1;
+ if (erp_next->er_extcount <=
+ (XFS_LINEAR_EXTS - erp->er_extcount)) {
+ memcpy(&erp->er_extbuf[erp->er_extcount],
+ erp_next->er_extbuf, erp_next->er_extcount *
+ sizeof(xfs_bmbt_rec_t));
+ erp->er_extcount += erp_next->er_extcount;
+ /*
+ * Free page before removing extent record
+ * so er_extoffs don't get modified in
+ * xfs_iext_irec_remove.
+ */
+ kmem_free(erp_next->er_extbuf);
+ erp_next->er_extbuf = NULL;
+ xfs_iext_irec_remove(ifp, erp_idx + 1);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ } else {
+ erp_idx++;
+ }
+ }
+}
+
+/*
+ * This is called to update the er_extoff field in the indirection
+ * array when extents have been added or removed from one of the
+ * extent lists. erp_idx contains the irec index to begin updating
+ * at and ext_diff contains the number of extents that were added
+ * or removed.
+ */
+void
+xfs_iext_irec_update_extoffs(
+ xfs_ifork_t *ifp, /* inode fork pointer */
+ int erp_idx, /* irec index to update */
+ int ext_diff) /* number of new extents */
+{
+ int i; /* loop counter */
+ int nlists; /* number of irec's (ex lists */
+
+ ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+ nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+ for (i = erp_idx; i < nlists; i++) {
+ ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
+ }
+}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (26 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 27/49] xfs: move inode fork definitions to a new header file Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-05 21:57 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations Dave Chinner
` (21 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 +
include/libxfs.h | 1 +
include/xfs_inode.h | 36 ------------------------------------
include/xfs_trans.h | 7 +++++++
libxfs/xfs.h | 3 +++
5 files changed, 12 insertions(+), 36 deletions(-)
diff --git a/include/Makefile b/include/Makefile
index 3d1ba0a..f84ff92 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -31,6 +31,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_ialloc.h \
xfs_ialloc_btree.h \
xfs_inode.h \
+ xfs_inode_fork.h \
xfs_inum.h \
xfs_log_format.h \
xfs_log_recover.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index 181fe3c..321b122 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -54,6 +54,7 @@
#include <xfs/xfs_ialloc_btree.h>
#include <xfs/xfs_attr_sf.h>
#include <xfs/xfs_dinode.h>
+#include <xfs/xfs_inode_fork.h>
#include <xfs/xfs_inode.h>
#include <xfs/xfs_alloc.h>
#include <xfs/xfs_btree.h>
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 6ee8bb7..99c034e 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -34,35 +34,6 @@ struct xfs_imap {
ushort im_boffset; /* inode offset in block in bytes */
};
-/*
- * This is the xfs in-core inode structure.
- * Most of the on-disk inode is embedded in the i_d field.
- *
- * The extent pointers/inline file space, however, are managed
- * separately. The memory for this information is pointed to by
- * the if_u1 unions depending on the type of the data.
- * This is used to linearize the array of extents for fast in-core
- * access. This is used until the file's number of extents
- * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers
- * are accessed through the buffer cache.
- *
- * Other state kept in the in-core inode is used for identification,
- * locking, transactional updating, etc of the inode.
- *
- * Generally, we do not want to hold the i_rlock while holding the
- * i_ilock. Hierarchy is i_iolock followed by i_rlock.
- *
- * xfs_iptr_t contains all the inode fields up to and including the
- * i_mnext and i_mprev fields, it is used as a marker in the inode
- * chain off the mount structure by xfs_sync calls.
- */
-/*
- * Flags for xfs_ichgtime().
- */
-#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
-#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
-#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
-
#ifdef __KERNEL__
@@ -398,13 +369,6 @@ do { \
#endif /* __KERNEL__ */
-/*
- * Flags for xfs_iget()
- */
-#define XFS_IGET_CREATE 0x1
-#define XFS_IGET_UNTRUSTED 0x2
-#define XFS_IGET_DONTCACHE 0x4
-
int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
struct xfs_imap *, struct xfs_dinode **,
struct xfs_buf **, uint, uint);
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index e504103..37aca08 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -89,6 +89,13 @@ struct xfs_log_item_desc {
#define XFS_ATTR_BTREE_REF 1
#define XFS_DQUOT_REF 1
+/*
+ * Flags for xfs_trans_ichgtime().
+ */
+#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
+#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
+#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
+
#ifdef __KERNEL__
struct xfs_buf;
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 7149c09..1a01c61 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -68,6 +68,9 @@ typedef __uint32_t inst_t; /* an instruction */
#define IHOLD(ip) ((void) 0)
+#define XFS_IGET_CREATE 0x1
+#define XFS_IGET_UNTRUSTED 0x2
+
/* stop unused var warnings by assigning mp to itself */
#define XFS_CORRUPTION_ERROR(e,l,mp,m) do { \
(mp) = (mp); \
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (27 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 13:25 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 30/49] xfs: split out the remote symlink handling Dave Chinner
` (20 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The only thing remaining in xfs_inode.[ch] are the operations that
read, write or verify physical inodes in their underlying buffers.
Move all this code to xfs_inode_buf.[ch] and so we can stop sharing
xfs_inode.[ch] with userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 2 +-
include/libxfs.h | 2 +-
include/xfs_inode.h | 393 ---------------------------------------------
include/xfs_inode_buf.h | 53 ++++++
libxfs/Makefile | 2 +-
libxfs/init.c | 3 +-
libxfs/xfs_inode.c | 419 ------------------------------------------------
libxfs/xfs_inode_buf.c | 408 ++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 466 insertions(+), 816 deletions(-)
delete mode 100644 include/xfs_inode.h
create mode 100644 include/xfs_inode_buf.h
delete mode 100644 libxfs/xfs_inode.c
create mode 100644 libxfs/xfs_inode_buf.c
diff --git a/include/Makefile b/include/Makefile
index f84ff92..2b121e5 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -30,7 +30,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_format.h \
xfs_ialloc.h \
xfs_ialloc_btree.h \
- xfs_inode.h \
+ xfs_inode_buf.h \
xfs_inode_fork.h \
xfs_inum.h \
xfs_log_format.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index 321b122..f84b816 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -55,7 +55,7 @@
#include <xfs/xfs_attr_sf.h>
#include <xfs/xfs_dinode.h>
#include <xfs/xfs_inode_fork.h>
-#include <xfs/xfs_inode.h>
+#include <xfs/xfs_inode_buf.h>
#include <xfs/xfs_alloc.h>
#include <xfs/xfs_btree.h>
#include <xfs/xfs_btree_trace.h>
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
deleted file mode 100644
index 99c034e..0000000
--- a/include/xfs_inode.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_INODE_H__
-#define __XFS_INODE_H__
-
-struct posix_acl;
-struct xfs_dinode;
-struct xfs_inode;
-
-#include "xfs_inode_fork.h"
-
-/*
- * Inode location information. Stored in the inode and passed to
- * xfs_imap_to_bp() to get a buffer and dinode for a given inode.
- */
-struct xfs_imap {
- xfs_daddr_t im_blkno; /* starting BB of inode chunk */
- ushort im_len; /* length in BBs of inode chunk */
- ushort im_boffset; /* inode offset in block in bytes */
-};
-
-
-#ifdef __KERNEL__
-
-struct xfs_buf;
-struct xfs_bmap_free;
-struct xfs_bmbt_irec;
-struct xfs_inode_log_item;
-struct xfs_mount;
-struct xfs_trans;
-struct xfs_dquot;
-
-typedef struct xfs_inode {
- /* Inode linking and identification information. */
- struct xfs_mount *i_mount; /* fs mount struct ptr */
- struct xfs_dquot *i_udquot; /* user dquot */
- struct xfs_dquot *i_gdquot; /* group dquot */
-
- /* Inode location stuff */
- xfs_ino_t i_ino; /* inode number (agno/agino)*/
- struct xfs_imap i_imap; /* location for xfs_imap() */
-
- /* Extent information. */
- xfs_ifork_t *i_afp; /* attribute fork pointer */
- xfs_ifork_t i_df; /* data fork */
-
- /* Transaction and locking information. */
- struct xfs_inode_log_item *i_itemp; /* logging information */
- mrlock_t i_lock; /* inode lock */
- mrlock_t i_iolock; /* inode IO lock */
- atomic_t i_pincount; /* inode pin count */
- spinlock_t i_flags_lock; /* inode i_flags lock */
- /* Miscellaneous state. */
- unsigned long i_flags; /* see defined flags below */
- unsigned int i_delayed_blks; /* count of delay alloc blks */
-
- xfs_icdinode_t i_d; /* most of ondisk inode */
-
- /* VFS inode */
- struct inode i_vnode; /* embedded VFS inode */
-} xfs_inode_t;
-
-/* Convert from vfs inode to xfs inode */
-static inline struct xfs_inode *XFS_I(struct inode *inode)
-{
- return container_of(inode, struct xfs_inode, i_vnode);
-}
-
-/* convert from xfs inode to vfs inode */
-static inline struct inode *VFS_I(struct xfs_inode *ip)
-{
- return &ip->i_vnode;
-}
-
-/*
- * For regular files we only update the on-disk filesize when actually
- * writing data back to disk. Until then only the copy in the VFS inode
- * is uptodate.
- */
-static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
-{
- if (S_ISREG(ip->i_d.di_mode))
- return i_size_read(VFS_I(ip));
- return ip->i_d.di_size;
-}
-
-/*
- * If this I/O goes past the on-disk inode size update it unless it would
- * be past the current in-core inode size.
- */
-static inline xfs_fsize_t
-xfs_new_eof(struct xfs_inode *ip, xfs_fsize_t new_size)
-{
- xfs_fsize_t i_size = i_size_read(VFS_I(ip));
-
- if (new_size > i_size)
- new_size = i_size;
- return new_size > ip->i_d.di_size ? new_size : 0;
-}
-
-/*
- * i_flags helper functions
- */
-static inline void
-__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
-{
- ip->i_flags |= flags;
-}
-
-static inline void
-xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
-{
- spin_lock(&ip->i_flags_lock);
- __xfs_iflags_set(ip, flags);
- spin_unlock(&ip->i_flags_lock);
-}
-
-static inline void
-xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags)
-{
- spin_lock(&ip->i_flags_lock);
- ip->i_flags &= ~flags;
- spin_unlock(&ip->i_flags_lock);
-}
-
-static inline int
-__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
-{
- return (ip->i_flags & flags);
-}
-
-static inline int
-xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
-{
- int ret;
- spin_lock(&ip->i_flags_lock);
- ret = __xfs_iflags_test(ip, flags);
- spin_unlock(&ip->i_flags_lock);
- return ret;
-}
-
-static inline int
-xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags)
-{
- int ret;
-
- spin_lock(&ip->i_flags_lock);
- ret = ip->i_flags & flags;
- if (ret)
- ip->i_flags &= ~flags;
- spin_unlock(&ip->i_flags_lock);
- return ret;
-}
-
-static inline int
-xfs_iflags_test_and_set(xfs_inode_t *ip, unsigned short flags)
-{
- int ret;
-
- spin_lock(&ip->i_flags_lock);
- ret = ip->i_flags & flags;
- if (!ret)
- ip->i_flags |= flags;
- spin_unlock(&ip->i_flags_lock);
- return ret;
-}
-
-/*
- * Project quota id helpers (previously projid was 16bit only
- * and using two 16bit values to hold new 32bit projid was chosen
- * to retain compatibility with "old" filesystems).
- */
-static inline prid_t
-xfs_get_projid(struct xfs_inode *ip)
-{
- return (prid_t)ip->i_d.di_projid_hi << 16 | ip->i_d.di_projid_lo;
-}
-
-static inline void
-xfs_set_projid(struct xfs_inode *ip,
- prid_t projid)
-{
- ip->i_d.di_projid_hi = (__uint16_t) (projid >> 16);
- ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
-}
-
-/*
- * In-core inode flags.
- */
-#define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */
-#define XFS_ISTALE (1 << 1) /* inode has been staled */
-#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */
-#define XFS_INEW (1 << 3) /* inode has just been allocated */
-#define XFS_IFILESTREAM (1 << 4) /* inode is in a filestream dir. */
-#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */
-#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
-#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */
-#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT)
-#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */
-#define XFS_IPINNED (1 << __XFS_IPINNED_BIT)
-#define XFS_IDONTCACHE (1 << 9) /* don't cache the inode long term */
-
-/*
- * Per-lifetime flags need to be reset when re-using a reclaimable inode during
- * inode lookup. This prevents unintended behaviour on the new inode from
- * ocurring.
- */
-#define XFS_IRECLAIM_RESET_FLAGS \
- (XFS_IRECLAIMABLE | XFS_IRECLAIM | \
- XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | \
- XFS_IFILESTREAM);
-
-/*
- * Synchronize processes attempting to flush the in-core inode back to disk.
- */
-
-extern void __xfs_iflock(struct xfs_inode *ip);
-
-static inline int xfs_iflock_nowait(struct xfs_inode *ip)
-{
- return !xfs_iflags_test_and_set(ip, XFS_IFLOCK);
-}
-
-static inline void xfs_iflock(struct xfs_inode *ip)
-{
- if (!xfs_iflock_nowait(ip))
- __xfs_iflock(ip);
-}
-
-static inline void xfs_ifunlock(struct xfs_inode *ip)
-{
- xfs_iflags_clear(ip, XFS_IFLOCK);
- smp_mb();
- wake_up_bit(&ip->i_flags, __XFS_IFLOCK_BIT);
-}
-
-static inline int xfs_isiflocked(struct xfs_inode *ip)
-{
- return xfs_iflags_test(ip, XFS_IFLOCK);
-}
-
-/*
- * Flags for inode locking.
- * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
- * 1<<16 - 1<<32-1 -- lockdep annotation (integers)
- */
-#define XFS_IOLOCK_EXCL (1<<0)
-#define XFS_IOLOCK_SHARED (1<<1)
-#define XFS_ILOCK_EXCL (1<<2)
-#define XFS_ILOCK_SHARED (1<<3)
-
-#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
- | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)
-
-#define XFS_LOCK_FLAGS \
- { XFS_IOLOCK_EXCL, "IOLOCK_EXCL" }, \
- { XFS_IOLOCK_SHARED, "IOLOCK_SHARED" }, \
- { XFS_ILOCK_EXCL, "ILOCK_EXCL" }, \
- { XFS_ILOCK_SHARED, "ILOCK_SHARED" }
-
-
-/*
- * Flags for lockdep annotations.
- *
- * XFS_LOCK_PARENT - for directory operations that require locking a
- * parent directory inode and a child entry inode. The parent gets locked
- * with this flag so it gets a lockdep subclass of 1 and the child entry
- * lock will have a lockdep subclass of 0.
- *
- * XFS_LOCK_RTBITMAP/XFS_LOCK_RTSUM - the realtime device bitmap and summary
- * inodes do not participate in the normal lock order, and thus have their
- * own subclasses.
- *
- * XFS_LOCK_INUMORDER - for locking several inodes at the some time
- * with xfs_lock_inodes(). This flag is used as the starting subclass
- * and each subsequent lock acquired will increment the subclass by one.
- * So the first lock acquired will have a lockdep subclass of 4, the
- * second lock will have a lockdep subclass of 5, and so on. It is
- * the responsibility of the class builder to shift this to the correct
- * portion of the lock_mode lockdep mask.
- */
-#define XFS_LOCK_PARENT 1
-#define XFS_LOCK_RTBITMAP 2
-#define XFS_LOCK_RTSUM 3
-#define XFS_LOCK_INUMORDER 4
-
-#define XFS_IOLOCK_SHIFT 16
-#define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT)
-
-#define XFS_ILOCK_SHIFT 24
-#define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT)
-#define XFS_ILOCK_RTBITMAP (XFS_LOCK_RTBITMAP << XFS_ILOCK_SHIFT)
-#define XFS_ILOCK_RTSUM (XFS_LOCK_RTSUM << XFS_ILOCK_SHIFT)
-
-#define XFS_IOLOCK_DEP_MASK 0x00ff0000
-#define XFS_ILOCK_DEP_MASK 0xff000000
-#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
-
-#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
-#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
-
-/*
- * For multiple groups support: if S_ISGID bit is set in the parent
- * directory, group of new file is set to that of the parent, and
- * new subdirectory gets S_ISGID bit from parent.
- */
-#define XFS_INHERIT_GID(pip) \
- (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
- ((pip)->i_d.di_mode & S_ISGID))
-
-
-/*
- * xfs_inode.c prototypes.
- */
-void xfs_ilock(xfs_inode_t *, uint);
-int xfs_ilock_nowait(xfs_inode_t *, uint);
-void xfs_iunlock(xfs_inode_t *, uint);
-void xfs_ilock_demote(xfs_inode_t *, uint);
-int xfs_isilocked(xfs_inode_t *, uint);
-uint xfs_ilock_map_shared(xfs_inode_t *);
-void xfs_iunlock_map_shared(xfs_inode_t *, uint);
-int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
- xfs_nlink_t, xfs_dev_t, prid_t, int,
- struct xfs_buf **, xfs_inode_t **);
-
-uint xfs_ip2xflags(struct xfs_inode *);
-uint xfs_dic2xflags(struct xfs_dinode *);
-int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
- struct xfs_bmap_free *);
-int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *,
- int, xfs_fsize_t);
-int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
-
-void xfs_iext_realloc(xfs_inode_t *, int, int);
-void xfs_iunpin_wait(xfs_inode_t *);
-int xfs_iflush(struct xfs_inode *, struct xfs_buf **);
-void xfs_lock_inodes(xfs_inode_t **, int, uint);
-void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
-
-xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip);
-
-#define IHOLD(ip) \
-do { \
- ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \
- ihold(VFS_I(ip)); \
- trace_xfs_ihold(ip, _THIS_IP_); \
-} while (0)
-
-#define IRELE(ip) \
-do { \
- trace_xfs_irele(ip, _THIS_IP_); \
- iput(VFS_I(ip)); \
-} while (0)
-
-#endif /* __KERNEL__ */
-
-int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
- struct xfs_imap *, struct xfs_dinode **,
- struct xfs_buf **, uint, uint);
-int xfs_iread(struct xfs_mount *, struct xfs_trans *,
- struct xfs_inode *, uint);
-void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
-void xfs_dinode_to_disk(struct xfs_dinode *,
- struct xfs_icdinode *);
-bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
-
-#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
-
-#if defined(DEBUG)
-void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
-#else
-#define xfs_inobp_check(mp, bp)
-#endif /* DEBUG */
-
-extern struct kmem_zone *xfs_inode_zone;
-extern const struct xfs_buf_ops xfs_inode_buf_ops;
-
-#endif /* __XFS_INODE_H__ */
diff --git a/include/xfs_inode_buf.h b/include/xfs_inode_buf.h
new file mode 100644
index 0000000..b5f1e22
--- /dev/null
+++ b/include/xfs_inode_buf.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __XFS_INODE_BUF_H__
+#define __XFS_INODE_BUF_H__
+
+struct xfs_inode;
+struct xfs_dinode;
+struct xfs_icdinode;
+
+/*
+ * Inode location information. Stored in the inode and passed to
+ * xfs_imap_to_bp() to get a buffer and dinode for a given inode.
+ */
+struct xfs_imap {
+ xfs_daddr_t im_blkno; /* starting BB of inode chunk */
+ ushort im_len; /* length in BBs of inode chunk */
+ ushort im_boffset; /* inode offset in block in bytes */
+};
+
+int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
+ struct xfs_imap *, struct xfs_dinode **,
+ struct xfs_buf **, uint, uint);
+int xfs_iread(struct xfs_mount *, struct xfs_trans *,
+ struct xfs_inode *, uint);
+void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
+void xfs_dinode_to_disk(struct xfs_dinode *,
+ struct xfs_icdinode *);
+bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
+
+#if defined(DEBUG)
+void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
+#else
+#define xfs_inobp_check(mp, bp)
+#endif /* DEBUG */
+
+extern const struct xfs_buf_ops xfs_inode_buf_ops;
+
+#endif /* __XFS_INODE_BUF_H__ */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index ed978f9..b7df144 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -16,7 +16,7 @@ CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_alloc_btree.c \
xfs_btree.c \
xfs_ialloc.c \
- xfs_inode.c \
+ xfs_inode_buf.c \
xfs_inode_fork.c \
xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \
xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \
diff --git a/libxfs/init.c b/libxfs/init.c
index e62f26a..5c418bc 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -32,6 +32,8 @@ int use_xfs_buf_lock; /* global flag: use xfs_buf_t locks for MT */
static void manage_zones(int); /* setup global zones */
+kmem_zone_t *xfs_inode_zone;
+
/*
* dev_map - map open devices to fd.
*/
@@ -369,7 +371,6 @@ manage_zones(int release)
{
extern kmem_zone_t *xfs_buf_zone;
extern kmem_zone_t *xfs_ili_zone;
- extern kmem_zone_t *xfs_inode_zone;
extern kmem_zone_t *xfs_ifork_zone;
extern kmem_zone_t *xfs_buf_item_zone;
extern kmem_zone_t *xfs_da_state_zone;
diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c
deleted file mode 100644
index 7efe1b3..0000000
--- a/libxfs/xfs_inode.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <xfs.h>
-
-kmem_zone_t *xfs_inode_zone;
-
-/*
- * Used in xfs_itruncate_extents(). This is the maximum number of extents
- * freed from a file in a single transaction.
- */
-#define XFS_ITRUNC_MAX_EXTENTS 2
-
-/*
- * Check that none of the inode's in the buffer have a next
- * unlinked field of 0.
- */
-#if defined(DEBUG)
-void
-xfs_inobp_check(
- xfs_mount_t *mp,
- xfs_buf_t *bp)
-{
- int i;
- int j;
- xfs_dinode_t *dip;
-
- j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
-
- for (i = 0; i < j; i++) {
- dip = (xfs_dinode_t *)xfs_buf_offset(bp,
- i * mp->m_sb.sb_inodesize);
- if (!dip->di_next_unlinked) {
- xfs_alert(mp,
- "Detected bogus zero next_unlinked field in incore inode buffer 0x%p.",
- bp);
- ASSERT(dip->di_next_unlinked);
- }
- }
-}
-#endif
-
-static void
-xfs_inode_buf_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- int i;
- int ni;
-
- /*
- * Validate the magic number and version of every inode in the buffer
- */
- ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock;
- for (i = 0; i < ni; i++) {
- int di_ok;
- xfs_dinode_t *dip;
-
- dip = (struct xfs_dinode *)xfs_buf_offset(bp,
- (i << mp->m_sb.sb_inodelog));
- di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) &&
- XFS_DINODE_GOOD_VERSION(dip->di_version);
- if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
- XFS_ERRTAG_ITOBP_INOTOBP,
- XFS_RANDOM_ITOBP_INOTOBP))) {
- xfs_buf_ioerror(bp, EFSCORRUPTED);
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
- mp, dip);
-#ifdef DEBUG
- xfs_emerg(mp,
- "bad inode magic/vsn daddr %lld #%d (magic=%x)",
- (unsigned long long)bp->b_bn, i,
- be16_to_cpu(dip->di_magic));
- ASSERT(0);
-#endif
- }
- }
- xfs_inobp_check(mp, bp);
-}
-
-
-static void
-xfs_inode_buf_read_verify(
- struct xfs_buf *bp)
-{
- xfs_inode_buf_verify(bp);
-}
-
-static void
-xfs_inode_buf_write_verify(
- struct xfs_buf *bp)
-{
- xfs_inode_buf_verify(bp);
-}
-
-const struct xfs_buf_ops xfs_inode_buf_ops = {
- .verify_read = xfs_inode_buf_read_verify,
- .verify_write = xfs_inode_buf_write_verify,
-};
-
-
-/*
- * This routine is called to map an inode to the buffer containing the on-disk
- * version of the inode. It returns a pointer to the buffer containing the
- * on-disk inode in the bpp parameter, and in the dipp parameter it returns a
- * pointer to the on-disk inode within that buffer.
- *
- * If a non-zero error is returned, then the contents of bpp and dipp are
- * undefined.
- */
-int
-xfs_imap_to_bp(
- struct xfs_mount *mp,
- struct xfs_trans *tp,
- struct xfs_imap *imap,
- struct xfs_dinode **dipp,
- struct xfs_buf **bpp,
- uint buf_flags,
- uint iget_flags)
-{
- struct xfs_buf *bp;
- int error;
-
- buf_flags |= XBF_UNMAPPED;
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
- (int)imap->im_len, buf_flags, &bp,
- &xfs_inode_buf_ops);
- if (error) {
- if (error == EAGAIN) {
- ASSERT(buf_flags & XBF_TRYLOCK);
- return error;
- }
-
- if (error == EFSCORRUPTED &&
- (iget_flags & XFS_IGET_UNTRUSTED))
- return XFS_ERROR(EINVAL);
-
- xfs_warn(mp, "%s: xfs_trans_read_buf() returned error %d.",
- __func__, error);
- return error;
- }
-
- *bpp = bp;
- *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset);
- return 0;
-}
-
-void
-xfs_dinode_from_disk(
- xfs_icdinode_t *to,
- xfs_dinode_t *from)
-{
- to->di_magic = be16_to_cpu(from->di_magic);
- to->di_mode = be16_to_cpu(from->di_mode);
- to->di_version = from ->di_version;
- to->di_format = from->di_format;
- to->di_onlink = be16_to_cpu(from->di_onlink);
- to->di_uid = be32_to_cpu(from->di_uid);
- to->di_gid = be32_to_cpu(from->di_gid);
- to->di_nlink = be32_to_cpu(from->di_nlink);
- to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
- to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
- memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
- to->di_flushiter = be16_to_cpu(from->di_flushiter);
- to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
- to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
- to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
- to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
- to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
- to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
- to->di_size = be64_to_cpu(from->di_size);
- to->di_nblocks = be64_to_cpu(from->di_nblocks);
- to->di_extsize = be32_to_cpu(from->di_extsize);
- to->di_nextents = be32_to_cpu(from->di_nextents);
- to->di_anextents = be16_to_cpu(from->di_anextents);
- to->di_forkoff = from->di_forkoff;
- to->di_aformat = from->di_aformat;
- to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
- to->di_dmstate = be16_to_cpu(from->di_dmstate);
- to->di_flags = be16_to_cpu(from->di_flags);
- to->di_gen = be32_to_cpu(from->di_gen);
-
- if (to->di_version == 3) {
- to->di_changecount = be64_to_cpu(from->di_changecount);
- to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
- to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
- to->di_flags2 = be64_to_cpu(from->di_flags2);
- to->di_ino = be64_to_cpu(from->di_ino);
- to->di_lsn = be64_to_cpu(from->di_lsn);
- memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
- platform_uuid_copy(&to->di_uuid, &from->di_uuid);
- }
-}
-
-void
-xfs_dinode_to_disk(
- xfs_dinode_t *to,
- xfs_icdinode_t *from)
-{
- to->di_magic = cpu_to_be16(from->di_magic);
- to->di_mode = cpu_to_be16(from->di_mode);
- to->di_version = from ->di_version;
- to->di_format = from->di_format;
- to->di_onlink = cpu_to_be16(from->di_onlink);
- to->di_uid = cpu_to_be32(from->di_uid);
- to->di_gid = cpu_to_be32(from->di_gid);
- to->di_nlink = cpu_to_be32(from->di_nlink);
- to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
- to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
- memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
- to->di_flushiter = cpu_to_be16(from->di_flushiter);
- to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
- to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
- to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
- to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
- to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
- to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
- to->di_size = cpu_to_be64(from->di_size);
- to->di_nblocks = cpu_to_be64(from->di_nblocks);
- to->di_extsize = cpu_to_be32(from->di_extsize);
- to->di_nextents = cpu_to_be32(from->di_nextents);
- to->di_anextents = cpu_to_be16(from->di_anextents);
- to->di_forkoff = from->di_forkoff;
- to->di_aformat = from->di_aformat;
- to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
- to->di_dmstate = cpu_to_be16(from->di_dmstate);
- to->di_flags = cpu_to_be16(from->di_flags);
- to->di_gen = cpu_to_be32(from->di_gen);
-
- if (from->di_version == 3) {
- to->di_changecount = cpu_to_be64(from->di_changecount);
- to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
- to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
- to->di_flags2 = cpu_to_be64(from->di_flags2);
- to->di_ino = cpu_to_be64(from->di_ino);
- to->di_lsn = cpu_to_be64(from->di_lsn);
- memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
- platform_uuid_copy(&to->di_uuid, &from->di_uuid);
- }
-}
-
-static bool
-xfs_dinode_verify(
- struct xfs_mount *mp,
- struct xfs_inode *ip,
- struct xfs_dinode *dip)
-{
- if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
- return false;
-
- /* only version 3 or greater inodes are extensively verified here */
- if (dip->di_version < 3)
- return true;
-
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return false;
- if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
- offsetof(struct xfs_dinode, di_crc)))
- return false;
- if (be64_to_cpu(dip->di_ino) != ip->i_ino)
- return false;
- if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid))
- return false;
- return true;
-}
-void
-xfs_dinode_calc_crc(
- struct xfs_mount *mp,
- struct xfs_dinode *dip)
-{
- __uint32_t crc;
-
- if (dip->di_version < 3)
- return;
-
- ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
- crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
- offsetof(struct xfs_dinode, di_crc));
- dip->di_crc = xfs_end_cksum(crc);
-}
-
-/*
- * Read the disk inode attributes into the in-core inode structure.
- */
-int
-xfs_iread(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- uint iget_flags)
-{
- xfs_buf_t *bp;
- xfs_dinode_t *dip;
- int error;
-
- /*
- * Fill in the location information in the in-core inode.
- */
- error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
- if (error)
- return error;
-
- /*
- * Get pointers to the on-disk inode and the buffer containing it.
- */
- error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags);
- if (error)
- return error;
-
- /* even unallocated inodes are verified */
- if (!xfs_dinode_verify(mp, ip, dip)) {
- xfs_alert(mp, "%s: validation failed for inode %lld failed",
- __func__, ip->i_ino);
-
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip);
- error = XFS_ERROR(EFSCORRUPTED);
- goto out_brelse;
- }
-
- /*
- * If the on-disk inode is already linked to a directory
- * entry, copy all of the inode into the in-core inode.
- * xfs_iformat_fork() handles copying in the inode format
- * specific information.
- * Otherwise, just get the truly permanent information.
- */
- if (dip->di_mode) {
- xfs_dinode_from_disk(&ip->i_d, dip);
- error = xfs_iformat_fork(ip, dip);
- if (error) {
-#ifdef DEBUG
- xfs_alert(mp, "%s: xfs_iformat() returned error %d",
- __func__, error);
-#endif /* DEBUG */
- goto out_brelse;
- }
- } else {
- /*
- * Partial initialisation of the in-core inode. Just the bits
- * that xfs_ialloc won't overwrite or relies on being correct.
- */
- ip->i_d.di_magic = be16_to_cpu(dip->di_magic);
- ip->i_d.di_version = dip->di_version;
- ip->i_d.di_gen = be32_to_cpu(dip->di_gen);
- ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter);
-
- if (dip->di_version == 3) {
- ip->i_d.di_ino = be64_to_cpu(dip->di_ino);
- uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid);
- }
-
- /*
- * Make sure to pull in the mode here as well in
- * case the inode is released without being used.
- * This ensures that xfs_inactive() will see that
- * the inode is already free and not try to mess
- * with the uninitialized part of it.
- */
- ip->i_d.di_mode = 0;
- }
-
- /*
- * The inode format changed when we moved the link count and
- * made it 32 bits long. If this is an old format inode,
- * convert it in memory to look like a new one. If it gets
- * flushed to disk we will convert back before flushing or
- * logging it. We zero out the new projid field and the old link
- * count field. We'll handle clearing the pad field (the remains
- * of the old uuid field) when we actually convert the inode to
- * the new format. We don't change the version number so that we
- * can distinguish this from a real new format inode.
- */
- if (ip->i_d.di_version == 1) {
- ip->i_d.di_nlink = ip->i_d.di_onlink;
- ip->i_d.di_onlink = 0;
- xfs_set_projid(&ip->i_d, 0);
- }
-
- ip->i_delayed_blks = 0;
-
- /*
- * Mark the buffer containing the inode as something to keep
- * around for a while. This helps to keep recently accessed
- * meta-data in-core longer.
- */
- xfs_buf_set_ref(bp, XFS_INO_REF);
-
- /*
- * Use xfs_trans_brelse() to release the buffer containing the
- * on-disk inode, because it was acquired with xfs_trans_read_buf()
- * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal
- * brelse(). If we're within a transaction, then xfs_trans_brelse()
- * will only release the buffer if it is not dirty within the
- * transaction. It will be OK to release the buffer in this case,
- * because inodes on disk are never destroyed and we will be
- * locking the new in-core inode before putting it in the hash
- * table where other processes can find it. Thus we don't have
- * to worry about the inode being changed just because we released
- * the buffer.
- */
- out_brelse:
- xfs_trans_brelse(tp, bp);
- return error;
-}
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
new file mode 100644
index 0000000..3c811f5
--- /dev/null
+++ b/libxfs/xfs_inode_buf.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <xfs.h>
+
+/*
+ * Check that none of the inode's in the buffer have a next
+ * unlinked field of 0.
+ */
+#if defined(DEBUG)
+void
+xfs_inobp_check(
+ xfs_mount_t *mp,
+ xfs_buf_t *bp)
+{
+ int i;
+ int j;
+ xfs_dinode_t *dip;
+
+ j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
+
+ for (i = 0; i < j; i++) {
+ dip = (xfs_dinode_t *)xfs_buf_offset(bp,
+ i * mp->m_sb.sb_inodesize);
+ if (!dip->di_next_unlinked) {
+ xfs_alert(mp,
+ "Detected bogus zero next_unlinked field in incore inode buffer 0x%p.",
+ bp);
+ ASSERT(dip->di_next_unlinked);
+ }
+ }
+}
+#endif
+
+static void
+xfs_inode_buf_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ int i;
+ int ni;
+
+ /*
+ * Validate the magic number and version of every inode in the buffer
+ */
+ ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock;
+ for (i = 0; i < ni; i++) {
+ int di_ok;
+ xfs_dinode_t *dip;
+
+ dip = (struct xfs_dinode *)xfs_buf_offset(bp,
+ (i << mp->m_sb.sb_inodelog));
+ di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) &&
+ XFS_DINODE_GOOD_VERSION(dip->di_version);
+ if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
+ XFS_ERRTAG_ITOBP_INOTOBP,
+ XFS_RANDOM_ITOBP_INOTOBP))) {
+ xfs_buf_ioerror(bp, EFSCORRUPTED);
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
+ mp, dip);
+#ifdef DEBUG
+ xfs_emerg(mp,
+ "bad inode magic/vsn daddr %lld #%d (magic=%x)",
+ (unsigned long long)bp->b_bn, i,
+ be16_to_cpu(dip->di_magic));
+ ASSERT(0);
+#endif
+ }
+ }
+ xfs_inobp_check(mp, bp);
+}
+
+static void
+xfs_inode_buf_read_verify(
+ struct xfs_buf *bp)
+{
+ xfs_inode_buf_verify(bp);
+}
+
+static void
+xfs_inode_buf_write_verify(
+ struct xfs_buf *bp)
+{
+ xfs_inode_buf_verify(bp);
+}
+
+const struct xfs_buf_ops xfs_inode_buf_ops = {
+ .verify_read = xfs_inode_buf_read_verify,
+ .verify_write = xfs_inode_buf_write_verify,
+};
+
+/*
+ * This routine is called to map an inode to the buffer containing the on-disk
+ * version of the inode. It returns a pointer to the buffer containing the
+ * on-disk inode in the bpp parameter, and in the dipp parameter it returns a
+ * pointer to the on-disk inode within that buffer.
+ *
+ * If a non-zero error is returned, then the contents of bpp and dipp are
+ * undefined.
+ */
+int
+xfs_imap_to_bp(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_imap *imap,
+ struct xfs_dinode **dipp,
+ struct xfs_buf **bpp,
+ uint buf_flags,
+ uint iget_flags)
+{
+ struct xfs_buf *bp;
+ int error;
+
+ buf_flags |= XBF_UNMAPPED;
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
+ (int)imap->im_len, buf_flags, &bp,
+ &xfs_inode_buf_ops);
+ if (error) {
+ if (error == EAGAIN) {
+ ASSERT(buf_flags & XBF_TRYLOCK);
+ return error;
+ }
+
+ if (error == EFSCORRUPTED &&
+ (iget_flags & XFS_IGET_UNTRUSTED))
+ return XFS_ERROR(EINVAL);
+
+ xfs_warn(mp, "%s: xfs_trans_read_buf() returned error %d.",
+ __func__, error);
+ return error;
+ }
+
+ *bpp = bp;
+ *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset);
+ return 0;
+}
+
+void
+xfs_dinode_from_disk(
+ xfs_icdinode_t *to,
+ xfs_dinode_t *from)
+{
+ to->di_magic = be16_to_cpu(from->di_magic);
+ to->di_mode = be16_to_cpu(from->di_mode);
+ to->di_version = from ->di_version;
+ to->di_format = from->di_format;
+ to->di_onlink = be16_to_cpu(from->di_onlink);
+ to->di_uid = be32_to_cpu(from->di_uid);
+ to->di_gid = be32_to_cpu(from->di_gid);
+ to->di_nlink = be32_to_cpu(from->di_nlink);
+ to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
+ to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
+ to->di_flushiter = be16_to_cpu(from->di_flushiter);
+ to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
+ to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
+ to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
+ to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
+ to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
+ to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
+ to->di_size = be64_to_cpu(from->di_size);
+ to->di_nblocks = be64_to_cpu(from->di_nblocks);
+ to->di_extsize = be32_to_cpu(from->di_extsize);
+ to->di_nextents = be32_to_cpu(from->di_nextents);
+ to->di_anextents = be16_to_cpu(from->di_anextents);
+ to->di_forkoff = from->di_forkoff;
+ to->di_aformat = from->di_aformat;
+ to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
+ to->di_dmstate = be16_to_cpu(from->di_dmstate);
+ to->di_flags = be16_to_cpu(from->di_flags);
+ to->di_gen = be32_to_cpu(from->di_gen);
+
+ if (to->di_version == 3) {
+ to->di_changecount = be64_to_cpu(from->di_changecount);
+ to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
+ to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
+ to->di_flags2 = be64_to_cpu(from->di_flags2);
+ to->di_ino = be64_to_cpu(from->di_ino);
+ to->di_lsn = be64_to_cpu(from->di_lsn);
+ memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
+ platform_uuid_copy(&to->di_uuid, &from->di_uuid);
+ }
+}
+
+void
+xfs_dinode_to_disk(
+ xfs_dinode_t *to,
+ xfs_icdinode_t *from)
+{
+ to->di_magic = cpu_to_be16(from->di_magic);
+ to->di_mode = cpu_to_be16(from->di_mode);
+ to->di_version = from ->di_version;
+ to->di_format = from->di_format;
+ to->di_onlink = cpu_to_be16(from->di_onlink);
+ to->di_uid = cpu_to_be32(from->di_uid);
+ to->di_gid = cpu_to_be32(from->di_gid);
+ to->di_nlink = cpu_to_be32(from->di_nlink);
+ to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
+ to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
+ to->di_flushiter = cpu_to_be16(from->di_flushiter);
+ to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
+ to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
+ to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
+ to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
+ to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
+ to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
+ to->di_size = cpu_to_be64(from->di_size);
+ to->di_nblocks = cpu_to_be64(from->di_nblocks);
+ to->di_extsize = cpu_to_be32(from->di_extsize);
+ to->di_nextents = cpu_to_be32(from->di_nextents);
+ to->di_anextents = cpu_to_be16(from->di_anextents);
+ to->di_forkoff = from->di_forkoff;
+ to->di_aformat = from->di_aformat;
+ to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
+ to->di_dmstate = cpu_to_be16(from->di_dmstate);
+ to->di_flags = cpu_to_be16(from->di_flags);
+ to->di_gen = cpu_to_be32(from->di_gen);
+
+ if (from->di_version == 3) {
+ to->di_changecount = cpu_to_be64(from->di_changecount);
+ to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
+ to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
+ to->di_flags2 = cpu_to_be64(from->di_flags2);
+ to->di_ino = cpu_to_be64(from->di_ino);
+ to->di_lsn = cpu_to_be64(from->di_lsn);
+ memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
+ platform_uuid_copy(&to->di_uuid, &from->di_uuid);
+ }
+}
+
+static bool
+xfs_dinode_verify(
+ struct xfs_mount *mp,
+ struct xfs_inode *ip,
+ struct xfs_dinode *dip)
+{
+ if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
+ return false;
+
+ /* only version 3 or greater inodes are extensively verified here */
+ if (dip->di_version < 3)
+ return true;
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return false;
+ if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
+ offsetof(struct xfs_dinode, di_crc)))
+ return false;
+ if (be64_to_cpu(dip->di_ino) != ip->i_ino)
+ return false;
+ if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid))
+ return false;
+ return true;
+}
+void
+xfs_dinode_calc_crc(
+ struct xfs_mount *mp,
+ struct xfs_dinode *dip)
+{
+ __uint32_t crc;
+
+ if (dip->di_version < 3)
+ return;
+
+ ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
+ crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
+ offsetof(struct xfs_dinode, di_crc));
+ dip->di_crc = xfs_end_cksum(crc);
+}
+
+/*
+ * Read the disk inode attributes into the in-core inode structure.
+ */
+int
+xfs_iread(
+ xfs_mount_t *mp,
+ xfs_trans_t *tp,
+ xfs_inode_t *ip,
+ uint iget_flags)
+{
+ xfs_buf_t *bp;
+ xfs_dinode_t *dip;
+ int error;
+
+ /*
+ * Fill in the location information in the in-core inode.
+ */
+ error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
+ if (error)
+ return error;
+
+ /*
+ * Get pointers to the on-disk inode and the buffer containing it.
+ */
+ error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags);
+ if (error)
+ return error;
+
+ /* even unallocated inodes are verified */
+ if (!xfs_dinode_verify(mp, ip, dip)) {
+ xfs_alert(mp, "%s: validation failed for inode %lld failed",
+ __func__, ip->i_ino);
+
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip);
+ error = XFS_ERROR(EFSCORRUPTED);
+ goto out_brelse;
+ }
+
+ /*
+ * If the on-disk inode is already linked to a directory
+ * entry, copy all of the inode into the in-core inode.
+ * xfs_iformat_fork() handles copying in the inode format
+ * specific information.
+ * Otherwise, just get the truly permanent information.
+ */
+ if (dip->di_mode) {
+ xfs_dinode_from_disk(&ip->i_d, dip);
+ error = xfs_iformat_fork(ip, dip);
+ if (error) {
+#ifdef DEBUG
+ xfs_alert(mp, "%s: xfs_iformat() returned error %d",
+ __func__, error);
+#endif /* DEBUG */
+ goto out_brelse;
+ }
+ } else {
+ /*
+ * Partial initialisation of the in-core inode. Just the bits
+ * that xfs_ialloc won't overwrite or relies on being correct.
+ */
+ ip->i_d.di_magic = be16_to_cpu(dip->di_magic);
+ ip->i_d.di_version = dip->di_version;
+ ip->i_d.di_gen = be32_to_cpu(dip->di_gen);
+ ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter);
+
+ if (dip->di_version == 3) {
+ ip->i_d.di_ino = be64_to_cpu(dip->di_ino);
+ uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid);
+ }
+
+ /*
+ * Make sure to pull in the mode here as well in
+ * case the inode is released without being used.
+ * This ensures that xfs_inactive() will see that
+ * the inode is already free and not try to mess
+ * with the uninitialized part of it.
+ */
+ ip->i_d.di_mode = 0;
+ }
+
+ /*
+ * The inode format changed when we moved the link count and
+ * made it 32 bits long. If this is an old format inode,
+ * convert it in memory to look like a new one. If it gets
+ * flushed to disk we will convert back before flushing or
+ * logging it. We zero out the new projid field and the old link
+ * count field. We'll handle clearing the pad field (the remains
+ * of the old uuid field) when we actually convert the inode to
+ * the new format. We don't change the version number so that we
+ * can distinguish this from a real new format inode.
+ */
+ if (ip->i_d.di_version == 1) {
+ ip->i_d.di_nlink = ip->i_d.di_onlink;
+ ip->i_d.di_onlink = 0;
+ xfs_set_projid(&ip->i_d, 0);
+ }
+
+ ip->i_delayed_blks = 0;
+
+ /*
+ * Mark the buffer containing the inode as something to keep
+ * around for a while. This helps to keep recently accessed
+ * meta-data in-core longer.
+ */
+ xfs_buf_set_ref(bp, XFS_INO_REF);
+
+ /*
+ * Use xfs_trans_brelse() to release the buffer containing the on-disk
+ * inode, because it was acquired with xfs_trans_read_buf() in
+ * xfs_imap_to_bp() above. If tp is NULL, this is just a normal
+ * brelse(). If we're within a transaction, then xfs_trans_brelse()
+ * will only release the buffer if it is not dirty within the
+ * transaction. It will be OK to release the buffer in this case,
+ * because inodes on disk are never destroyed and we will be locking the
+ * new in-core inode before putting it in the cache where other
+ * processes can find it. Thus we don't have to worry about the inode
+ * being changed just because we released the buffer.
+ */
+ out_brelse:
+ xfs_trans_brelse(tp, bp);
+ return error;
+}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 30/49] xfs: split out the remote symlink handling
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (28 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-07-19 6:45 ` [PATCH 31/49] libxfs: switch over to xfs_sb.c and remove xfs_mount.c Dave Chinner
` (19 subsequent siblings)
49 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The remote symlink format definition and manipulation needs to be
shared with userspace, but the in-kernel interfaces do not. Split
the remote symlink format handling out into xfs_symlink_remote.[ch]
fo it can easily be shared with userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 -
include/libxfs.h | 1 -
include/xfs_format.h | 42 ++++++++++
include/xfs_symlink.h | 47 -----------
libxfs/Makefile | 2 +-
libxfs/xfs_symlink.c | 176 -----------------------------------------
libxfs/xfs_symlink_remote.c | 185 ++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 228 insertions(+), 226 deletions(-)
delete mode 100644 include/xfs_symlink.h
delete mode 100644 libxfs/xfs_symlink.c
create mode 100644 libxfs/xfs_symlink_remote.c
diff --git a/include/Makefile b/include/Makefile
index 2b121e5..70720e5 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -39,7 +39,6 @@ QAHFILES = libxfs.h libxlog.h \
xfs_mount.h \
xfs_quota_defs.h \
xfs_sb.h \
- xfs_symlink.h \
xfs_trace.h \
xfs_trans.h \
xfs_trans_resv.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index f84b816..37e9e15 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -61,7 +61,6 @@
#include <xfs/xfs_btree_trace.h>
#include <xfs/xfs_bmap.h>
#include <xfs/xfs_trace.h>
-#include <xfs/xfs_symlink.h>
#ifndef ARRAY_SIZE
diff --git a/include/xfs_format.h b/include/xfs_format.h
index 6205374..35c08ff 100644
--- a/include/xfs_format.h
+++ b/include/xfs_format.h
@@ -27,6 +27,12 @@
* xfs_log_format.h. Everything else goes here.
*/
+struct xfs_mount;
+struct xfs_trans;
+struct xfs_inode;
+struct xfs_buf;
+struct xfs_ifork;
+
/*
* RealTime Device format definitions
*/
@@ -123,5 +129,41 @@ typedef struct xfs_dqblk {
#define XFS_DQUOT_CRC_OFF offsetof(struct xfs_dqblk, dd_crc)
+/*
+ * Remote symlink format and access functions.
+ */
+#define XFS_SYMLINK_MAGIC 0x58534c4d /* XSLM */
+
+struct xfs_dsymlink_hdr {
+ __be32 sl_magic;
+ __be32 sl_offset;
+ __be32 sl_bytes;
+ __be32 sl_crc;
+ uuid_t sl_uuid;
+ __be64 sl_owner;
+ __be64 sl_blkno;
+ __be64 sl_lsn;
+};
+
+/*
+ * The maximum pathlen is 1024 bytes. Since the minimum file system
+ * blocksize is 512 bytes, we can get a max of 3 extents back from
+ * bmapi when crc headers are taken into account.
+ */
+#define XFS_SYMLINK_MAPS 3
+
+#define XFS_SYMLINK_BUF_SPACE(mp, bufsize) \
+ ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
+ sizeof(struct xfs_dsymlink_hdr) : 0))
+
+int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
+int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
+ uint32_t size, struct xfs_buf *bp);
+bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
+ uint32_t size, struct xfs_buf *bp);
+void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
+ struct xfs_inode *ip, struct xfs_ifork *ifp);
+
+extern const struct xfs_buf_ops xfs_symlink_buf_ops;
#endif /* __XFS_FORMAT_H__ */
diff --git a/include/xfs_symlink.h b/include/xfs_symlink.h
deleted file mode 100644
index e85dfd1..0000000
--- a/include/xfs_symlink.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012 Red Hat, Inc. All rights reserved.
- */
-#ifndef __XFS_SYMLINK_H
-#define __XFS_SYMLINK_H 1
-
-#define XFS_SYMLINK_MAGIC 0x58534c4d /* XSLM */
-
-struct xfs_dsymlink_hdr {
- __be32 sl_magic;
- __be32 sl_offset;
- __be32 sl_bytes;
- __be32 sl_crc;
- uuid_t sl_uuid;
- __be64 sl_owner;
- __be64 sl_blkno;
- __be64 sl_lsn;
-};
-
-/*
- * The maximum pathlen is 1024 bytes. Since the minimum file system
- * blocksize is 512 bytes, we can get a max of 3 extents back from
- * bmapi when crc headers are taken into account.
- */
-#define XFS_SYMLINK_MAPS 3
-
-#define XFS_SYMLINK_BUF_SPACE(mp, bufsize) \
- ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
- sizeof(struct xfs_dsymlink_hdr) : 0))
-
-int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
-bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
- uint32_t size, struct xfs_buf *bp);
-void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_inode *ip, struct xfs_ifork *ifp);
-
-extern const struct xfs_buf_ops xfs_symlink_buf_ops;
-
-#ifdef __KERNEL__
-
-int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
- const char *target_path, umode_t mode, struct xfs_inode **ipp);
-int xfs_readlink(struct xfs_inode *ip, char *link);
-int xfs_inactive_symlink_rmt(struct xfs_inode *ip, struct xfs_trans **tpp);
-
-#endif /* __KERNEL__ */
-#endif /* __XFS_SYMLINK_H */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index b7df144..6ba38f9 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -23,7 +23,7 @@ CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \
xfs_mount.c xfs_rtalloc.c xfs_attr.c xfs_attr_remote.c \
crc32.c \
- xfs_symlink.c \
+ xfs_symlink_remote.c \
xfs_trans_resv.c
CFILES += $(PKG_PLATFORM).c
diff --git a/libxfs/xfs_symlink.c b/libxfs/xfs_symlink.c
deleted file mode 100644
index f2e69f9..0000000
--- a/libxfs/xfs_symlink.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2013 Red Hat, Inc.
- * All rights reserved.
- */
-
-#include "xfs.h"
-
-/*
- * Each contiguous block has a header, so it is not just a simple pathlen
- * to FSB conversion.
- */
-int
-xfs_symlink_blocks(
- struct xfs_mount *mp,
- int pathlen)
-{
- int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
-
- return (pathlen + buflen - 1) / buflen;
-}
-
-/*
- * This is used by mkfs/proto.c to create symlinks.
- */
-int
-xfs_symlink_hdr_set(
- struct xfs_mount *mp,
- xfs_ino_t ino,
- uint32_t offset,
- uint32_t size,
- struct xfs_buf *bp)
-{
- struct xfs_dsymlink_hdr *dsl = bp->b_addr;
-
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return 0;
-
- dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);
- dsl->sl_offset = cpu_to_be32(offset);
- dsl->sl_bytes = cpu_to_be32(size);
- uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid);
- dsl->sl_owner = cpu_to_be64(ino);
- dsl->sl_blkno = cpu_to_be64(bp->b_bn);
- bp->b_ops = &xfs_symlink_buf_ops;
-
- return sizeof(struct xfs_dsymlink_hdr);
-}
-
-/*
- * Checking of the symlink header is split into two parts. the verifier does
- * CRC, location and bounds checking, the unpacking function checks the path
- * parameters and owner.
- */
-bool
-xfs_symlink_hdr_ok(
- struct xfs_mount *mp,
- xfs_ino_t ino,
- uint32_t offset,
- uint32_t size,
- struct xfs_buf *bp)
-{
- struct xfs_dsymlink_hdr *dsl = bp->b_addr;
-
- if (offset != be32_to_cpu(dsl->sl_offset))
- return false;
- if (size != be32_to_cpu(dsl->sl_bytes))
- return false;
- if (ino != be64_to_cpu(dsl->sl_owner))
- return false;
-
- /* ok */
- return true;
-
-}
-
-static bool
-xfs_symlink_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- struct xfs_dsymlink_hdr *dsl = bp->b_addr;
-
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return false;
- if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))
- return false;
- if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid))
- return false;
- if (bp->b_bn != be64_to_cpu(dsl->sl_blkno))
- return false;
- if (be32_to_cpu(dsl->sl_offset) +
- be32_to_cpu(dsl->sl_bytes) >= MAXPATHLEN)
- return false;
- if (dsl->sl_owner == 0)
- return false;
-
- return true;
-}
-
-static void
-xfs_symlink_read_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
-
- /* no verification of non-crc buffers */
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return;
-
- if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
- offsetof(struct xfs_dsymlink_hdr, sl_crc)) ||
- !xfs_symlink_verify(bp)) {
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
- xfs_buf_ioerror(bp, EFSCORRUPTED);
- }
-}
-
-static void
-xfs_symlink_write_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- struct xfs_buf_log_item *bip = bp->b_fspriv;
-
- /* no verification of non-crc buffers */
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return;
-
- if (!xfs_symlink_verify(bp)) {
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
- xfs_buf_ioerror(bp, EFSCORRUPTED);
- return;
- }
-
- if (bip) {
- struct xfs_dsymlink_hdr *dsl = bp->b_addr;
- dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
- }
- xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
- offsetof(struct xfs_dsymlink_hdr, sl_crc));
-}
-
-const struct xfs_buf_ops xfs_symlink_buf_ops = {
- .verify_read = xfs_symlink_read_verify,
- .verify_write = xfs_symlink_write_verify,
-};
-
-void
-xfs_symlink_local_to_remote(
- struct xfs_trans *tp,
- struct xfs_buf *bp,
- struct xfs_inode *ip,
- struct xfs_ifork *ifp)
-{
- struct xfs_mount *mp = ip->i_mount;
- char *buf;
-
- if (!xfs_sb_version_hascrc(&mp->m_sb)) {
- bp->b_ops = NULL;
- memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
- return;
- }
-
- /*
- * As this symlink fits in an inode literal area, it must also fit in
- * the smallest buffer the filesystem supports.
- */
- ASSERT(BBTOB(bp->b_length) >=
- ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr));
-
- bp->b_ops = &xfs_symlink_buf_ops;
-
- buf = bp->b_addr;
- buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp);
- memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes);
-}
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
new file mode 100644
index 0000000..539db0c
--- /dev/null
+++ b/libxfs/xfs_symlink_remote.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * Copyright (c) 2012-2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <xfs.h>
+
+/*
+ * Each contiguous block has a header, so it is not just a simple pathlen
+ * to FSB conversion.
+ */
+int
+xfs_symlink_blocks(
+ struct xfs_mount *mp,
+ int pathlen)
+{
+ int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
+
+ return (pathlen + buflen - 1) / buflen;
+}
+
+int
+xfs_symlink_hdr_set(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ uint32_t offset,
+ uint32_t size,
+ struct xfs_buf *bp)
+{
+ struct xfs_dsymlink_hdr *dsl = bp->b_addr;
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return 0;
+
+ dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);
+ dsl->sl_offset = cpu_to_be32(offset);
+ dsl->sl_bytes = cpu_to_be32(size);
+ uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid);
+ dsl->sl_owner = cpu_to_be64(ino);
+ dsl->sl_blkno = cpu_to_be64(bp->b_bn);
+ bp->b_ops = &xfs_symlink_buf_ops;
+
+ return sizeof(struct xfs_dsymlink_hdr);
+}
+
+/*
+ * Checking of the symlink header is split into two parts. the verifier does
+ * CRC, location and bounds checking, the unpacking function checks the path
+ * parameters and owner.
+ */
+bool
+xfs_symlink_hdr_ok(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ uint32_t offset,
+ uint32_t size,
+ struct xfs_buf *bp)
+{
+ struct xfs_dsymlink_hdr *dsl = bp->b_addr;
+
+ if (offset != be32_to_cpu(dsl->sl_offset))
+ return false;
+ if (size != be32_to_cpu(dsl->sl_bytes))
+ return false;
+ if (ino != be64_to_cpu(dsl->sl_owner))
+ return false;
+
+ /* ok */
+ return true;
+}
+
+static bool
+xfs_symlink_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_dsymlink_hdr *dsl = bp->b_addr;
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return false;
+ if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))
+ return false;
+ if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid))
+ return false;
+ if (bp->b_bn != be64_to_cpu(dsl->sl_blkno))
+ return false;
+ if (be32_to_cpu(dsl->sl_offset) +
+ be32_to_cpu(dsl->sl_bytes) >= MAXPATHLEN)
+ return false;
+ if (dsl->sl_owner == 0)
+ return false;
+
+ return true;
+}
+
+static void
+xfs_symlink_read_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+
+ /* no verification of non-crc buffers */
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return;
+
+ if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
+ offsetof(struct xfs_dsymlink_hdr, sl_crc)) ||
+ !xfs_symlink_verify(bp)) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+ xfs_buf_ioerror(bp, EFSCORRUPTED);
+ }
+}
+
+static void
+xfs_symlink_write_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_buf_log_item *bip = bp->b_fspriv;
+
+ /* no verification of non-crc buffers */
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return;
+
+ if (!xfs_symlink_verify(bp)) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+ xfs_buf_ioerror(bp, EFSCORRUPTED);
+ return;
+ }
+
+ if (bip) {
+ struct xfs_dsymlink_hdr *dsl = bp->b_addr;
+ dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
+ }
+ xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
+ offsetof(struct xfs_dsymlink_hdr, sl_crc));
+}
+
+const struct xfs_buf_ops xfs_symlink_buf_ops = {
+ .verify_read = xfs_symlink_read_verify,
+ .verify_write = xfs_symlink_write_verify,
+};
+
+void
+xfs_symlink_local_to_remote(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp,
+ struct xfs_inode *ip,
+ struct xfs_ifork *ifp)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ char *buf;
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+ bp->b_ops = NULL;
+ memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
+ return;
+ }
+
+ /*
+ * As this symlink fits in an inode literal area, it must also fit in
+ * the smallest buffer the filesystem supports.
+ */
+ ASSERT(BBTOB(bp->b_length) >=
+ ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr));
+
+ bp->b_ops = &xfs_symlink_buf_ops;
+
+ buf = bp->b_addr;
+ buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp);
+ memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes);
+}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 31/49] libxfs: switch over to xfs_sb.c and remove xfs_mount.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (29 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 30/49] xfs: split out the remote symlink handling Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-07-19 6:45 ` [PATCH 32/49] xfs: create xfs_bmap_util.[ch] Dave Chinner
` (18 subsequent siblings)
49 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Now that the kernel code has split the superblock specific code out
of xfs_mount.c, we don't need xfs_mount.c anymore. Copy in xfs_sb.c
and remove xfs_mount.c
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 -
include/libxfs.h | 14 +-
include/libxlog.h | 4 -
include/xfs_mount.h | 372 ---------------------------
include/xfs_sb.h | 26 ++
include/xfs_trace.h | 1 +
libxfs/Makefile | 10 +-
libxfs/init.c | 2 +-
libxfs/xfs.h | 1 +
libxfs/xfs_mount.c | 627 ---------------------------------------------
libxfs/xfs_sb.c | 721 ++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 768 insertions(+), 1011 deletions(-)
delete mode 100644 include/xfs_mount.h
delete mode 100644 libxfs/xfs_mount.c
create mode 100644 libxfs/xfs_sb.c
diff --git a/include/Makefile b/include/Makefile
index 70720e5..53821ee 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -36,7 +36,6 @@ QAHFILES = libxfs.h libxlog.h \
xfs_log_format.h \
xfs_log_recover.h \
xfs_metadump.h \
- xfs_mount.h \
xfs_quota_defs.h \
xfs_sb.h \
xfs_trace.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index 37e9e15..b4d2657 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -47,7 +47,6 @@
#include <xfs/xfs_sb.h>
#include <xfs/xfs_ag.h>
#include <xfs/xfs_dir2.h>
-#include <xfs/xfs_mount.h>
#include <xfs/xfs_da_btree.h>
#include <xfs/xfs_bmap_btree.h>
#include <xfs/xfs_alloc_btree.h>
@@ -323,6 +322,11 @@ enum xfs_buf_flags_t { /* b_flags bits */
#define xfs_buf_set_ref(bp,ref) ((void) 0)
#define xfs_buf_ioerror(bp,err) (bp)->b_error = (err);
+#define xfs_daddr_to_agno(mp,d) \
+ ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks))
+#define xfs_daddr_to_agbno(mp,d) \
+ ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks))
+
/* Buffer Cache Interfaces */
extern struct cache *libxfs_bcache;
@@ -476,7 +480,6 @@ extern xfs_trans_t *libxfs_trans_dup (xfs_trans_t *);
extern int libxfs_trans_reserve (xfs_trans_t *, uint,uint,uint,uint,uint);
extern int libxfs_trans_commit (xfs_trans_t *, uint);
extern void libxfs_trans_cancel (xfs_trans_t *, int);
-extern void libxfs_mod_sb (xfs_trans_t *, __int64_t);
extern xfs_buf_t *libxfs_trans_getsb (xfs_trans_t *, xfs_mount_t *, int);
extern int libxfs_trans_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t,
@@ -704,7 +707,7 @@ void xfs_dinode_from_disk(struct xfs_icdinode *,
#define libxfs_idata_realloc xfs_idata_realloc
#define libxfs_idestroy_fork xfs_idestroy_fork
-/* xfs_mount.h */
+/* xfs_sb.h */
#define libxfs_mod_sb xfs_mod_sb
#define libxfs_sb_from_disk xfs_sb_from_disk
#define libxfs_sb_to_disk xfs_sb_to_disk
@@ -729,4 +732,9 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len);
#include <xfs/xfs_cksum.h>
+#define xfs_notice(mp,fmt,args...) cmn_err(CE_NOTE,fmt, ## args)
+#define xfs_warn(mp,fmt,args...) cmn_err(CE_WARN,fmt, ## args)
+#define xfs_alert(mp,fmt,args...) cmn_err(CE_ALERT,fmt, ## args)
+#define xfs_hex_dump(d,n) ((void) 0)
+
#endif /* __LIBXFS_H__ */
diff --git a/include/libxlog.h b/include/libxlog.h
index e65b607..a61e437 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -66,10 +66,6 @@ struct xlog {
#define XFS_MOUNT_WAS_CLEAN 0x1
#define unlikely(x) (x)
-#define xfs_warn(mp,fmt,args...) cmn_err(CE_WARN,fmt, ## args)
-#define xfs_alert(mp,fmt,args...) cmn_err(CE_ALERT,fmt, ## args)
-#define xfs_hex_dump(d,n) ((void) 0)
-
extern void xlog_warn(char *fmt,...);
extern void xlog_exit(char *fmt,...);
extern void xlog_panic(char *fmt,...);
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
deleted file mode 100644
index 5410e9f..0000000
--- a/include/xfs_mount.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_MOUNT_H__
-#define __XFS_MOUNT_H__
-
-#ifndef __KERNEL__
-
-#define xfs_daddr_to_agno(mp,d) \
- ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks))
-#define xfs_daddr_to_agbno(mp,d) \
- ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks))
-
-#else /* __KERNEL__ */
-
-struct xlog;
-struct xfs_inode;
-struct xfs_mru_cache;
-struct xfs_nameops;
-struct xfs_ail;
-struct xfs_quotainfo;
-
-#ifdef HAVE_PERCPU_SB
-
-/*
- * Valid per-cpu incore superblock counters. Note that if you add new counters,
- * you may need to define new counter disabled bit field descriptors as there
- * are more possible fields in the superblock that can fit in a bitfield on a
- * 32 bit platform. The XFS_SBS_* values for the current current counters just
- * fit.
- */
-typedef struct xfs_icsb_cnts {
- uint64_t icsb_fdblocks;
- uint64_t icsb_ifree;
- uint64_t icsb_icount;
- unsigned long icsb_flags;
-} xfs_icsb_cnts_t;
-
-#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */
-
-#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */
-
-extern int xfs_icsb_init_counters(struct xfs_mount *);
-extern void xfs_icsb_reinit_counters(struct xfs_mount *);
-extern void xfs_icsb_destroy_counters(struct xfs_mount *);
-extern void xfs_icsb_sync_counters(struct xfs_mount *, int);
-extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int);
-extern int xfs_icsb_modify_counters(struct xfs_mount *, xfs_sb_field_t,
- int64_t, int);
-
-#else
-#define xfs_icsb_init_counters(mp) (0)
-#define xfs_icsb_destroy_counters(mp) do { } while (0)
-#define xfs_icsb_reinit_counters(mp) do { } while (0)
-#define xfs_icsb_sync_counters(mp, flags) do { } while (0)
-#define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0)
-#define xfs_icsb_modify_counters(mp, field, delta, rsvd) \
- xfs_mod_incore_sb(mp, field, delta, rsvd)
-#endif
-
-/* dynamic preallocation free space thresholds, 5% down to 1% */
-enum {
- XFS_LOWSP_1_PCNT = 0,
- XFS_LOWSP_2_PCNT,
- XFS_LOWSP_3_PCNT,
- XFS_LOWSP_4_PCNT,
- XFS_LOWSP_5_PCNT,
- XFS_LOWSP_MAX,
-};
-
-typedef struct xfs_mount {
- struct super_block *m_super;
- xfs_tid_t m_tid; /* next unused tid for fs */
- struct xfs_ail *m_ail; /* fs active log item list */
- xfs_sb_t m_sb; /* copy of fs superblock */
- spinlock_t m_sb_lock; /* sb counter lock */
- struct xfs_buf *m_sb_bp; /* buffer for superblock */
- char *m_fsname; /* filesystem name */
- int m_fsname_len; /* strlen of fs name */
- char *m_rtname; /* realtime device name */
- char *m_logname; /* external log device name */
- int m_bsize; /* fs logical block size */
- xfs_agnumber_t m_agfrotor; /* last ag where space found */
- xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
- spinlock_t m_agirotor_lock;/* .. and lock protecting it */
- xfs_agnumber_t m_maxagi; /* highest inode alloc group */
- uint m_readio_log; /* min read size log bytes */
- uint m_readio_blocks; /* min read size blocks */
- uint m_writeio_log; /* min write size log bytes */
- uint m_writeio_blocks; /* min write size blocks */
- struct xlog *m_log; /* log specific stuff */
- int m_logbufs; /* number of log buffers */
- int m_logbsize; /* size of each log buffer */
- uint m_rsumlevels; /* rt summary levels */
- uint m_rsumsize; /* size of rt summary, bytes */
- struct xfs_inode *m_rbmip; /* pointer to bitmap inode */
- struct xfs_inode *m_rsumip; /* pointer to summary inode */
- struct xfs_inode *m_rootip; /* pointer to root directory */
- struct xfs_quotainfo *m_quotainfo; /* disk quota information */
- xfs_buftarg_t *m_ddev_targp; /* saves taking the address */
- xfs_buftarg_t *m_logdev_targp;/* ptr to log device */
- xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */
- __uint8_t m_blkbit_log; /* blocklog + NBBY */
- __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
- __uint8_t m_agno_log; /* log #ag's */
- __uint8_t m_agino_log; /* #bits for agino in inum */
- __uint16_t m_inode_cluster_size;/* min inode buf size */
- uint m_blockmask; /* sb_blocksize-1 */
- uint m_blockwsize; /* sb_blocksize in words */
- uint m_blockwmask; /* blockwsize-1 */
- uint m_alloc_mxr[2]; /* max alloc btree records */
- uint m_alloc_mnr[2]; /* min alloc btree records */
- uint m_bmap_dmxr[2]; /* max bmap btree records */
- uint m_bmap_dmnr[2]; /* min bmap btree records */
- uint m_inobt_mxr[2]; /* max inobt btree records */
- uint m_inobt_mnr[2]; /* min inobt btree records */
- uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */
- uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
- uint m_in_maxlevels; /* max inobt btree levels. */
- struct radix_tree_root m_perag_tree; /* per-ag accounting info */
- spinlock_t m_perag_lock; /* lock for m_perag_tree */
- struct mutex m_growlock; /* growfs mutex */
- int m_fixedfsid[2]; /* unchanged for life of FS */
- uint m_dmevmask; /* DMI events for this FS */
- __uint64_t m_flags; /* global mount flags */
- uint m_dir_node_ents; /* #entries in a dir danode */
- uint m_attr_node_ents; /* #entries in attr danode */
- int m_ialloc_inos; /* inodes in inode allocation */
- int m_ialloc_blks; /* blocks in inode allocation */
- int m_inoalign_mask;/* mask sb_inoalignmt if used */
- uint m_qflags; /* quota status flags */
- struct xfs_trans_resv m_reservations; /* precomputed res values */
- __uint64_t m_maxicount; /* maximum inode count */
- __uint64_t m_resblks; /* total reserved blocks */
- __uint64_t m_resblks_avail;/* available reserved blocks */
- __uint64_t m_resblks_save; /* reserved blks @ remount,ro */
- int m_dalign; /* stripe unit */
- int m_swidth; /* stripe width */
- int m_sinoalign; /* stripe unit inode alignment */
- int m_attr_magicpct;/* 37% of the blocksize */
- int m_dir_magicpct; /* 37% of the dir blocksize */
- __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
- const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
- int m_dirblksize; /* directory block sz--bytes */
- int m_dirblkfsbs; /* directory block sz--fsbs */
- xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
- xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
- xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
- uint m_chsize; /* size of next field */
- struct xfs_chash *m_chash; /* fs private inode per-cluster
- * hash table */
- atomic_t m_active_trans; /* number trans frozen */
-#ifdef HAVE_PERCPU_SB
- xfs_icsb_cnts_t __percpu *m_sb_cnts; /* per-cpu superblock counters */
- unsigned long m_icsb_counters; /* disabled per-cpu counters */
- struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */
- struct mutex m_icsb_mutex; /* balancer sync lock */
-#endif
- struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
- struct delayed_work m_reclaim_work; /* background inode reclaim */
- struct delayed_work m_eofblocks_work; /* background eof blocks
- trimming */
- __int64_t m_update_flags; /* sb flags we need to update
- on the next remount,rw */
- int64_t m_low_space[XFS_LOWSP_MAX];
- /* low free space thresholds */
-
- struct workqueue_struct *m_data_workqueue;
- struct workqueue_struct *m_unwritten_workqueue;
- struct workqueue_struct *m_cil_workqueue;
- struct workqueue_struct *m_reclaim_workqueue;
- struct workqueue_struct *m_log_workqueue;
- struct workqueue_struct *m_eofblocks_workqueue;
-} xfs_mount_t;
-
-/*
- * Flags for m_flags.
- */
-#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
- must be synchronous except
- for space allocations */
-#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
-#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
- operations, typically for
- disk errors in metadata */
-#define XFS_MOUNT_DISCARD (1ULL << 5) /* discard unused blocks */
-#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to
- user */
-#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
- allocations */
-#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */
-#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */
-#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
-#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
-#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
- * 32 bits in size */
-#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
-#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
-#define XFS_MOUNT_BARRIER (1ULL << 17)
-#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/
-#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
- * allocation */
-#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */
-#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
-#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
- * I/O size in stat() */
-#define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams
- allocator */
-#define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */
-
-
-/*
- * Default minimum read and write sizes.
- */
-#define XFS_READIO_LOG_LARGE 16
-#define XFS_WRITEIO_LOG_LARGE 16
-
-/*
- * Max and min values for mount-option defined I/O
- * preallocation sizes.
- */
-#define XFS_MAX_IO_LOG 30 /* 1G */
-#define XFS_MIN_IO_LOG PAGE_SHIFT
-
-/*
- * Synchronous read and write sizes. This should be
- * better for NFSv2 wsync filesystems.
- */
-#define XFS_WSYNC_READIO_LOG 15 /* 32k */
-#define XFS_WSYNC_WRITEIO_LOG 14 /* 16k */
-
-/*
- * Allow large block sizes to be reported to userspace programs if the
- * "largeio" mount option is used.
- *
- * If compatibility mode is specified, simply return the basic unit of caching
- * so that we don't get inefficient read/modify/write I/O from user apps.
- * Otherwise....
- *
- * If the underlying volume is a stripe, then return the stripe width in bytes
- * as the recommended I/O size. It is not a stripe and we've set a default
- * buffered I/O size, return that, otherwise return the compat default.
- */
-static inline unsigned long
-xfs_preferred_iosize(xfs_mount_t *mp)
-{
- if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)
- return PAGE_CACHE_SIZE;
- return (mp->m_swidth ?
- (mp->m_swidth << mp->m_sb.sb_blocklog) :
- ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ?
- (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) :
- PAGE_CACHE_SIZE));
-}
-
-#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \
- ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
-#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
-void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
- int lnnum);
-#define xfs_force_shutdown(m,f) \
- xfs_do_force_shutdown(m, f, __FILE__, __LINE__)
-
-#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
-#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
-#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
-#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
-#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
-#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
-
-/*
- * Flags for xfs_mountfs
- */
-#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
-
-static inline xfs_agnumber_t
-xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d)
-{
- xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
- do_div(ld, mp->m_sb.sb_agblocks);
- return (xfs_agnumber_t) ld;
-}
-
-static inline xfs_agblock_t
-xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
-{
- xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
- return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks);
-}
-
-/*
- * Per-cpu superblock locking functions
- */
-#ifdef HAVE_PERCPU_SB
-static inline void
-xfs_icsb_lock(xfs_mount_t *mp)
-{
- mutex_lock(&mp->m_icsb_mutex);
-}
-
-static inline void
-xfs_icsb_unlock(xfs_mount_t *mp)
-{
- mutex_unlock(&mp->m_icsb_mutex);
-}
-#else
-#define xfs_icsb_lock(mp)
-#define xfs_icsb_unlock(mp)
-#endif
-
-/*
- * This structure is for use by the xfs_mod_incore_sb_batch() routine.
- * xfs_growfs can specify a few fields which are more than int limit
- */
-typedef struct xfs_mod_sb {
- xfs_sb_field_t msb_field; /* Field to modify, see below */
- int64_t msb_delta; /* Change to make to specified field */
-} xfs_mod_sb_t;
-
-extern int xfs_log_sbcount(xfs_mount_t *);
-extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
-extern int xfs_mountfs(xfs_mount_t *mp);
-
-extern void xfs_unmountfs(xfs_mount_t *);
-extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
-extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
- uint, int);
-extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
-extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
-extern int xfs_readsb(xfs_mount_t *, int);
-extern void xfs_freesb(xfs_mount_t *);
-extern int xfs_fs_writable(xfs_mount_t *);
-extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
-
-extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-
-extern void xfs_set_low_space_thresholds(struct xfs_mount *);
-
-#endif /* __KERNEL__ */
-
-/*
- * perag get/put wrappers for ref counting
- */
-struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
-struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
- int tag);
-void xfs_perag_put(struct xfs_perag *pag);
-
-extern void xfs_sb_calc_crc(struct xfs_buf *);
-extern void xfs_mod_sb(struct xfs_trans *, __int64_t);
-extern int xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t,
- xfs_agnumber_t *);
-extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
-extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
-
-extern const struct xfs_buf_ops xfs_sb_buf_ops;
-
-#endif /* __XFS_MOUNT_H__ */
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index 51db6f2..dea0373 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -26,6 +26,7 @@
struct xfs_buf;
struct xfs_mount;
+struct xfs_trans;
#define XFS_SB_MAGIC 0x58465342 /* 'XFSB' */
#define XFS_SB_VERSION_1 1 /* 5.3, 6.0.1, 6.1 */
@@ -625,6 +626,12 @@ xfs_sb_has_incompat_log_feature(
return (sbp->sb_features_log_incompat & feature) != 0;
}
+static inline bool
+xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
+{
+ return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
+}
+
/*
* end of superblock version macros
*/
@@ -661,4 +668,23 @@ xfs_sb_has_incompat_log_feature(
#define XFS_B_TO_FSBT(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_blocklog)
#define XFS_B_FSB_OFFSET(mp,b) ((b) & (mp)->m_blockmask)
+/*
+ * perag get/put wrappers for ref counting
+ */
+extern struct xfs_perag *xfs_perag_get(struct xfs_mount *, xfs_agnumber_t);
+extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t,
+ int tag);
+extern void xfs_perag_put(struct xfs_perag *pag);
+extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t);
+
+extern void xfs_sb_calc_crc(struct xfs_buf *);
+extern void xfs_mod_sb(struct xfs_trans *, __int64_t);
+extern void xfs_sb_mount_common(struct xfs_mount *, struct xfs_sb *);
+extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
+extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
+extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp);
+
+extern const struct xfs_buf_ops xfs_sb_buf_ops;
+extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
+
#endif /* __XFS_SB_H__ */
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index 5f32097..1d2728e 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -162,6 +162,7 @@
/* set c = c to avoid unused var warnings */
#define trace_xfs_perag_get(a,b,c,d) ((c) = (c))
+#define trace_xfs_perag_get_tag(a,b,c,d) ((c) = (c))
#define trace_xfs_perag_put(a,b,c,d) ((c) = (c))
#endif /* __TRACE_H__ */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 6ba38f9..5608020 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -11,9 +11,13 @@ LT_REVISION = 0
LT_AGE = 0
HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h
-CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
+CFILES = cache.c \
+ crc32.c \
+ init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_alloc.c \
xfs_alloc_btree.c \
+ xfs_attr.c \
+ xfs_attr_remote.c \
xfs_btree.c \
xfs_ialloc.c \
xfs_inode_buf.c \
@@ -21,8 +25,8 @@ CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \
xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \
xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \
xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \
- xfs_mount.c xfs_rtalloc.c xfs_attr.c xfs_attr_remote.c \
- crc32.c \
+ xfs_rtalloc.c \
+ xfs_sb.c \
xfs_symlink_remote.c \
xfs_trans_resv.c
diff --git a/libxfs/init.c b/libxfs/init.c
index 5c418bc..db7eeea 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -692,7 +692,7 @@ libxfs_mount(
INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
sbp = &(mp->m_sb);
- xfs_mount_common(mp, sb);
+ xfs_sb_mount_common(mp, sb);
xfs_alloc_compute_maxlevels(mp);
xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 1a01c61..0113b50 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -345,6 +345,7 @@ do { \
#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0)
#define xfs_icreate_log(tp, agno, agbno, cnt, isize, len, gen) ((void) 0)
+#define xfs_sb_validate_fsb_count(sbp, nblks) (0)
/*
* Prototypes for kernel static functions that are aren't in their
diff --git a/libxfs/xfs_mount.c b/libxfs/xfs_mount.c
deleted file mode 100644
index db3785d..0000000
--- a/libxfs/xfs_mount.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <xfs.h>
-
-static const struct {
- short offset;
- short type; /* 0 = integer
- * 1 = binary / string (no translation)
- */
-} xfs_sb_info[] = {
- { offsetof(xfs_sb_t, sb_magicnum), 0 },
- { offsetof(xfs_sb_t, sb_blocksize), 0 },
- { offsetof(xfs_sb_t, sb_dblocks), 0 },
- { offsetof(xfs_sb_t, sb_rblocks), 0 },
- { offsetof(xfs_sb_t, sb_rextents), 0 },
- { offsetof(xfs_sb_t, sb_uuid), 1 },
- { offsetof(xfs_sb_t, sb_logstart), 0 },
- { offsetof(xfs_sb_t, sb_rootino), 0 },
- { offsetof(xfs_sb_t, sb_rbmino), 0 },
- { offsetof(xfs_sb_t, sb_rsumino), 0 },
- { offsetof(xfs_sb_t, sb_rextsize), 0 },
- { offsetof(xfs_sb_t, sb_agblocks), 0 },
- { offsetof(xfs_sb_t, sb_agcount), 0 },
- { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
- { offsetof(xfs_sb_t, sb_logblocks), 0 },
- { offsetof(xfs_sb_t, sb_versionnum), 0 },
- { offsetof(xfs_sb_t, sb_sectsize), 0 },
- { offsetof(xfs_sb_t, sb_inodesize), 0 },
- { offsetof(xfs_sb_t, sb_inopblock), 0 },
- { offsetof(xfs_sb_t, sb_fname[0]), 1 },
- { offsetof(xfs_sb_t, sb_blocklog), 0 },
- { offsetof(xfs_sb_t, sb_sectlog), 0 },
- { offsetof(xfs_sb_t, sb_inodelog), 0 },
- { offsetof(xfs_sb_t, sb_inopblog), 0 },
- { offsetof(xfs_sb_t, sb_agblklog), 0 },
- { offsetof(xfs_sb_t, sb_rextslog), 0 },
- { offsetof(xfs_sb_t, sb_inprogress), 0 },
- { offsetof(xfs_sb_t, sb_imax_pct), 0 },
- { offsetof(xfs_sb_t, sb_icount), 0 },
- { offsetof(xfs_sb_t, sb_ifree), 0 },
- { offsetof(xfs_sb_t, sb_fdblocks), 0 },
- { offsetof(xfs_sb_t, sb_frextents), 0 },
- { offsetof(xfs_sb_t, sb_uquotino), 0 },
- { offsetof(xfs_sb_t, sb_gquotino), 0 },
- { offsetof(xfs_sb_t, sb_qflags), 0 },
- { offsetof(xfs_sb_t, sb_flags), 0 },
- { offsetof(xfs_sb_t, sb_shared_vn), 0 },
- { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
- { offsetof(xfs_sb_t, sb_unit), 0 },
- { offsetof(xfs_sb_t, sb_width), 0 },
- { offsetof(xfs_sb_t, sb_dirblklog), 0 },
- { offsetof(xfs_sb_t, sb_logsectlog), 0 },
- { offsetof(xfs_sb_t, sb_logsectsize),0 },
- { offsetof(xfs_sb_t, sb_logsunit), 0 },
- { offsetof(xfs_sb_t, sb_features2), 0 },
- { offsetof(xfs_sb_t, sb_bad_features2), 0 },
- { offsetof(xfs_sb_t, sb_features_compat), 0 },
- { offsetof(xfs_sb_t, sb_features_ro_compat), 0 },
- { offsetof(xfs_sb_t, sb_features_incompat), 0 },
- { offsetof(xfs_sb_t, sb_features_log_incompat), 0 },
- { offsetof(xfs_sb_t, sb_crc), 0 },
- { offsetof(xfs_sb_t, sb_pad), 0 },
- { offsetof(xfs_sb_t, sb_pquotino), 0 },
- { offsetof(xfs_sb_t, sb_lsn), 0 },
- { sizeof(xfs_sb_t), 0 }
-};
-
-/*
- * Reference counting access wrappers to the perag structures.
- * Because we never free per-ag structures, the only thing we
- * have to protect against changes is the tree structure itself.
- */
-struct xfs_perag *
-xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno)
-{
- struct xfs_perag *pag;
- int ref = 0;
-
- rcu_read_lock();
- pag = radix_tree_lookup(&mp->m_perag_tree, agno);
- if (pag) {
- ASSERT(atomic_read(&pag->pag_ref) >= 0);
- ref = atomic_inc_return(&pag->pag_ref);
- }
- rcu_read_unlock();
- trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
- return pag;
-}
-
-void
-xfs_perag_put(struct xfs_perag *pag)
-{
- int ref;
-
- ASSERT(atomic_read(&pag->pag_ref) > 0);
- ref = atomic_dec_return(&pag->pag_ref);
- trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
-}
-
-/*
- * Check the validity of the SB found.
- */
-STATIC int
-xfs_mount_validate_sb(
- xfs_mount_t *mp,
- xfs_sb_t *sbp,
- bool check_inprogress,
- bool check_version)
-{
-
- /*
- * If the log device and data device have the
- * same device number, the log is internal.
- * Consequently, the sb_logstart should be non-zero. If
- * we have a zero sb_logstart in this case, we may be trying to mount
- * a volume filesystem in a non-volume manner.
- */
- if (sbp->sb_magicnum != XFS_SB_MAGIC) {
- xfs_warn(mp, "bad magic number");
- return XFS_ERROR(EWRONGFS);
- }
-
-
- if (!xfs_sb_good_version(sbp)) {
- xfs_warn(mp, "bad version");
- return XFS_ERROR(EWRONGFS);
- }
-
- /*
- * Version 5 superblock feature mask validation. Reject combinations the
- * kernel cannot support up front before checking anything else.
- */
- if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
- xfs_alert(mp,
-"Version 5 superblock detected. xfsprogs has EXPERIMENTAL support enabled!\n"
-"Use of these features is at your own risk!");
-
- if (xfs_sb_has_compat_feature(sbp,
- XFS_SB_FEAT_COMPAT_UNKNOWN)) {
- xfs_warn(mp,
-"Superblock has unknown compatible features (0x%x) enabled.\n"
-"Using a more recent xfsprogs is recommended.",
- (sbp->sb_features_compat &
- XFS_SB_FEAT_COMPAT_UNKNOWN));
- }
-
- if (xfs_sb_has_ro_compat_feature(sbp,
- XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
- xfs_warn(mp,
-"Superblock has unknown read-only compatible features (0x%x) enabled.\n"
-"Using a more recent xfsprogs is recommended.",
- (sbp->sb_features_ro_compat &
- XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
- }
- if (xfs_sb_has_incompat_feature(sbp,
- XFS_SB_FEAT_INCOMPAT_UNKNOWN)) {
- xfs_warn(mp,
-"Superblock has unknown incompatible features (0x%x) enabled.\n"
-"Filesystem can not be safely operated on by this xfsprogs installation",
- (sbp->sb_features_incompat &
- XFS_SB_FEAT_INCOMPAT_UNKNOWN));
- return XFS_ERROR(EINVAL);
- }
- }
-
- if (unlikely(
- sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
- xfs_warn(mp,
- "filesystem is marked as having an external log; "
- "specify logdev on the mount command line.");
- return XFS_ERROR(EINVAL);
- }
-
- if (unlikely(
- sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
- xfs_warn(mp,
- "filesystem is marked as having an internal log; "
- "do not specify logdev on the mount command line.");
- return XFS_ERROR(EINVAL);
- }
-
- /*
- * More sanity checking. Most of these were stolen directly from
- * xfs_repair.
- */
- if (unlikely(
- sbp->sb_agcount <= 0 ||
- sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
- sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
- sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
- sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
- sbp->sb_sectsize != (1 << sbp->sb_sectlog) ||
- sbp->sb_blocksize < XFS_MIN_BLOCKSIZE ||
- sbp->sb_blocksize > XFS_MAX_BLOCKSIZE ||
- sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
- sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
- sbp->sb_blocksize != (1 << sbp->sb_blocklog) ||
- sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
- sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
- sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
- sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
- sbp->sb_inodesize != (1 << sbp->sb_inodelog) ||
- (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
- (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
- (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
- (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
- sbp->sb_dblocks == 0 ||
- sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
- sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) {
- XFS_CORRUPTION_ERROR("SB sanity check failed",
- XFS_ERRLEVEL_LOW, mp, sbp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- /*
- * Currently only very few inode sizes are supported.
- */
- switch (sbp->sb_inodesize) {
- case 256:
- case 512:
- case 1024:
- case 2048:
- break;
- default:
- xfs_warn(mp, "inode size of %d bytes not supported",
- sbp->sb_inodesize);
- return XFS_ERROR(ENOSYS);
- }
-
- /*
- * Version 1 directory format has never worked on Linux.
- */
- if (unlikely(!xfs_sb_version_hasdirv2(sbp))) {
- xfs_warn(mp, "file system using version 1 directory format");
- return XFS_ERROR(ENOSYS);
- }
-
- return 0;
-}
-
-void
-xfs_sb_from_disk(
- xfs_sb_t *to,
- xfs_dsb_t *from)
-{
- to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
- to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
- to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
- to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
- to->sb_rextents = be64_to_cpu(from->sb_rextents);
- memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
- to->sb_logstart = be64_to_cpu(from->sb_logstart);
- to->sb_rootino = be64_to_cpu(from->sb_rootino);
- to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
- to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
- to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
- to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
- to->sb_agcount = be32_to_cpu(from->sb_agcount);
- to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
- to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
- to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
- to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
- to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
- to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
- memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
- to->sb_blocklog = from->sb_blocklog;
- to->sb_sectlog = from->sb_sectlog;
- to->sb_inodelog = from->sb_inodelog;
- to->sb_inopblog = from->sb_inopblog;
- to->sb_agblklog = from->sb_agblklog;
- to->sb_rextslog = from->sb_rextslog;
- to->sb_inprogress = from->sb_inprogress;
- to->sb_imax_pct = from->sb_imax_pct;
- to->sb_icount = be64_to_cpu(from->sb_icount);
- to->sb_ifree = be64_to_cpu(from->sb_ifree);
- to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
- to->sb_frextents = be64_to_cpu(from->sb_frextents);
- to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
- to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
- to->sb_qflags = be16_to_cpu(from->sb_qflags);
- to->sb_flags = from->sb_flags;
- to->sb_shared_vn = from->sb_shared_vn;
- to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
- to->sb_unit = be32_to_cpu(from->sb_unit);
- to->sb_width = be32_to_cpu(from->sb_width);
- to->sb_dirblklog = from->sb_dirblklog;
- to->sb_logsectlog = from->sb_logsectlog;
- to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
- to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
- to->sb_features2 = be32_to_cpu(from->sb_features2);
- to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
- to->sb_features_compat = be32_to_cpu(from->sb_features_compat);
- to->sb_features_ro_compat = be32_to_cpu(from->sb_features_ro_compat);
- to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat);
- to->sb_features_log_incompat =
- be32_to_cpu(from->sb_features_log_incompat);
- to->sb_pad = 0;
- to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
- to->sb_lsn = be64_to_cpu(from->sb_lsn);
-}
-
-/*
- * Copy in core superblock to ondisk one.
- *
- * The fields argument is mask of superblock fields to copy.
- */
-void
-xfs_sb_to_disk(
- xfs_dsb_t *to,
- xfs_sb_t *from,
- __int64_t fields)
-{
- xfs_caddr_t to_ptr = (xfs_caddr_t)to;
- xfs_caddr_t from_ptr = (xfs_caddr_t)from;
- xfs_sb_field_t f;
- int first;
- int size;
-
- ASSERT(fields);
- if (!fields)
- return;
-
- while (fields) {
- f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
- first = xfs_sb_info[f].offset;
- size = xfs_sb_info[f + 1].offset - first;
-
- ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
-
- if (size == 1 || xfs_sb_info[f].type == 1) {
- memcpy(to_ptr + first, from_ptr + first, size);
- } else {
- switch (size) {
- case 2:
- *(__be16 *)(to_ptr + first) =
- cpu_to_be16(*(__u16 *)(from_ptr + first));
- break;
- case 4:
- *(__be32 *)(to_ptr + first) =
- cpu_to_be32(*(__u32 *)(from_ptr + first));
- break;
- case 8:
- *(__be64 *)(to_ptr + first) =
- cpu_to_be64(*(__u64 *)(from_ptr + first));
- break;
- default:
- ASSERT(0);
- }
- }
-
- fields &= ~(1LL << f);
- }
-}
-
-static int
-xfs_sb_verify(
- struct xfs_buf *bp,
- bool check_version)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- struct xfs_sb sb;
-
- xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp));
-
- /*
- * Only check the in progress field for the primary superblock as
- * mkfs.xfs doesn't clear it from secondary superblocks.
- */
- return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
- check_version);
-}
-
-/*
- * If the superblock has the CRC feature bit set or the CRC field is non-null,
- * check that the CRC is valid. We check the CRC field is non-null because a
- * single bit error could clear the feature bit and unused parts of the
- * superblock are supposed to be zero. Hence a non-null crc field indicates that
- * we've potentially lost a feature bit and we should check it anyway.
- */
-static void
-xfs_sb_read_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
- int error;
-
- /*
- * open code the version check to avoid needing to convert the entire
- * superblock from disk order just to check the version number
- */
- if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC) &&
- (((be16_to_cpu(dsb->sb_versionnum) & XFS_SB_VERSION_NUMBITS) ==
- XFS_SB_VERSION_5) ||
- dsb->sb_crc != 0)) {
-
- if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize),
- offsetof(struct xfs_sb, sb_crc))) {
- error = EFSCORRUPTED;
- goto out_error;
- }
- }
- error = xfs_sb_verify(bp, true);
-
-out_error:
- if (error) {
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
- xfs_buf_ioerror(bp, error);
- }
-}
-
-/*
- * We may be probed for a filesystem match, so we may not want to emit
- * messages when the superblock buffer is not actually an XFS superblock.
- * If we find an XFS superblock, the run a normal, noisy mount because we are
- * really going to mount it and want to know about errors.
- */
-static void
-xfs_sb_quiet_read_verify(
- struct xfs_buf *bp)
-{
- struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
-
-
- if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) {
- /* XFS filesystem, verify noisily! */
- xfs_sb_read_verify(bp);
- return;
- }
- /* quietly fail */
- xfs_buf_ioerror(bp, EWRONGFS);
-}
-
-static void
-xfs_sb_write_verify(
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = bp->b_target->bt_mount;
- struct xfs_buf_log_item *bip = bp->b_fspriv;
- int error;
-
- error = xfs_sb_verify(bp, false);
- if (error) {
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
- xfs_buf_ioerror(bp, error);
- return;
- }
-
- if (!xfs_sb_version_hascrc(&mp->m_sb))
- return;
-
- if (bip)
- XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
-
- xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
- offsetof(struct xfs_sb, sb_crc));
-}
-
-const struct xfs_buf_ops xfs_sb_buf_ops = {
- .verify_read = xfs_sb_read_verify,
- .verify_write = xfs_sb_write_verify,
-};
-
-static const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
- .verify_read = xfs_sb_quiet_read_verify,
- .verify_write = xfs_sb_write_verify,
-};
-
-/*
- * xfs_mount_common
- *
- * Mount initialization code establishing various mount
- * fields from the superblock associated with the given
- * mount structure
- *
- * Note: this requires user-space public scope for libxfs_mount
- */
-void
-xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
-{
- mp->m_agfrotor = mp->m_agirotor = 0;
- spin_lock_init(&mp->m_agirotor_lock);
- mp->m_maxagi = mp->m_sb.sb_agcount;
- mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
- mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
- mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
- mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
- mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
- mp->m_blockmask = sbp->sb_blocksize - 1;
- mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
- mp->m_blockwmask = mp->m_blockwsize - 1;
-
- mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
- mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
- mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
- mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2;
-
- mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
- mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
- mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2;
- mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2;
-
- mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1);
- mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
- mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
- mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2;
-
- mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
- mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
- sbp->sb_inopblock);
- mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
-}
-
-/*
- * xfs_initialize_perag_data
- *
- * Read in each per-ag structure so we can count up the number of
- * allocated inodes, free inodes and used filesystem blocks as this
- * information is no longer persistent in the superblock. Once we have
- * this information, write it into the in-core superblock structure.
- *
- * Note: this requires user-space public scope for libxfs_mount
- */
-int
-xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
-{
- xfs_agnumber_t index;
- xfs_perag_t *pag;
- xfs_sb_t *sbp = &mp->m_sb;
- uint64_t ifree = 0;
- uint64_t ialloc = 0;
- uint64_t bfree = 0;
- uint64_t bfreelst = 0;
- uint64_t btree = 0;
- int error;
-
- for (index = 0; index < agcount; index++) {
- /*
- * read the agf, then the agi. This gets us
- * all the information we need and populates the
- * per-ag structures for us.
- */
- error = xfs_alloc_pagf_init(mp, NULL, index, 0);
- if (error)
- return error;
-
- error = xfs_ialloc_pagi_init(mp, NULL, index);
- if (error)
- return error;
- pag = xfs_perag_get(mp, index);
- ifree += pag->pagi_freecount;
- ialloc += pag->pagi_count;
- bfree += pag->pagf_freeblks;
- bfreelst += pag->pagf_flcount;
- btree += pag->pagf_btreeblks;
- xfs_perag_put(pag);
- }
- /*
- * Overwrite incore superblock counters with just-read data
- */
- spin_lock(&mp->m_sb_lock);
- sbp->sb_ifree = ifree;
- sbp->sb_icount = ialloc;
- sbp->sb_fdblocks = bfree + bfreelst + btree;
- spin_unlock(&mp->m_sb_lock);
-
- /* Fixup the per-cpu counters as well. */
- xfs_icsb_reinit_counters(mp);
-
- return 0;
-}
-
-/*
- * xfs_mod_sb() can be used to copy arbitrary changes to the
- * in-core superblock into the superblock buffer to be logged.
- * It does not provide the higher level of locking that is
- * needed to protect the in-core superblock from concurrent
- * access.
- */
-void
-xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
-{
- xfs_buf_t *bp;
- int first;
- int last;
- xfs_mount_t *mp;
- xfs_sb_field_t f;
-
- ASSERT(fields);
- if (!fields)
- return;
- mp = tp->t_mountp;
- bp = xfs_trans_getsb(tp, mp, 0);
- first = sizeof(xfs_sb_t);
- last = 0;
-
- /* translate/copy */
- xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
-
- /* find modified range */
- f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
- ASSERT((1LL << f) & XFS_SB_MOD_BITS);
- last = xfs_sb_info[f + 1].offset - 1;
-
- f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
- ASSERT((1LL << f) & XFS_SB_MOD_BITS);
- first = xfs_sb_info[f].offset;
-
- xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
- xfs_trans_log_buf(tp, bp, first, last);
-}
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
new file mode 100644
index 0000000..869fb76
--- /dev/null
+++ b/libxfs/xfs_sb.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <xfs.h>
+
+/*
+ * Physical superblock buffer manipulations. Shared with libxfs in userspace.
+ */
+
+static const struct {
+ short offset;
+ short type; /* 0 = integer
+ * 1 = binary / string (no translation)
+ */
+} xfs_sb_info[] = {
+ { offsetof(xfs_sb_t, sb_magicnum), 0 },
+ { offsetof(xfs_sb_t, sb_blocksize), 0 },
+ { offsetof(xfs_sb_t, sb_dblocks), 0 },
+ { offsetof(xfs_sb_t, sb_rblocks), 0 },
+ { offsetof(xfs_sb_t, sb_rextents), 0 },
+ { offsetof(xfs_sb_t, sb_uuid), 1 },
+ { offsetof(xfs_sb_t, sb_logstart), 0 },
+ { offsetof(xfs_sb_t, sb_rootino), 0 },
+ { offsetof(xfs_sb_t, sb_rbmino), 0 },
+ { offsetof(xfs_sb_t, sb_rsumino), 0 },
+ { offsetof(xfs_sb_t, sb_rextsize), 0 },
+ { offsetof(xfs_sb_t, sb_agblocks), 0 },
+ { offsetof(xfs_sb_t, sb_agcount), 0 },
+ { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
+ { offsetof(xfs_sb_t, sb_logblocks), 0 },
+ { offsetof(xfs_sb_t, sb_versionnum), 0 },
+ { offsetof(xfs_sb_t, sb_sectsize), 0 },
+ { offsetof(xfs_sb_t, sb_inodesize), 0 },
+ { offsetof(xfs_sb_t, sb_inopblock), 0 },
+ { offsetof(xfs_sb_t, sb_fname[0]), 1 },
+ { offsetof(xfs_sb_t, sb_blocklog), 0 },
+ { offsetof(xfs_sb_t, sb_sectlog), 0 },
+ { offsetof(xfs_sb_t, sb_inodelog), 0 },
+ { offsetof(xfs_sb_t, sb_inopblog), 0 },
+ { offsetof(xfs_sb_t, sb_agblklog), 0 },
+ { offsetof(xfs_sb_t, sb_rextslog), 0 },
+ { offsetof(xfs_sb_t, sb_inprogress), 0 },
+ { offsetof(xfs_sb_t, sb_imax_pct), 0 },
+ { offsetof(xfs_sb_t, sb_icount), 0 },
+ { offsetof(xfs_sb_t, sb_ifree), 0 },
+ { offsetof(xfs_sb_t, sb_fdblocks), 0 },
+ { offsetof(xfs_sb_t, sb_frextents), 0 },
+ { offsetof(xfs_sb_t, sb_uquotino), 0 },
+ { offsetof(xfs_sb_t, sb_gquotino), 0 },
+ { offsetof(xfs_sb_t, sb_qflags), 0 },
+ { offsetof(xfs_sb_t, sb_flags), 0 },
+ { offsetof(xfs_sb_t, sb_shared_vn), 0 },
+ { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
+ { offsetof(xfs_sb_t, sb_unit), 0 },
+ { offsetof(xfs_sb_t, sb_width), 0 },
+ { offsetof(xfs_sb_t, sb_dirblklog), 0 },
+ { offsetof(xfs_sb_t, sb_logsectlog), 0 },
+ { offsetof(xfs_sb_t, sb_logsectsize),0 },
+ { offsetof(xfs_sb_t, sb_logsunit), 0 },
+ { offsetof(xfs_sb_t, sb_features2), 0 },
+ { offsetof(xfs_sb_t, sb_bad_features2), 0 },
+ { offsetof(xfs_sb_t, sb_features_compat), 0 },
+ { offsetof(xfs_sb_t, sb_features_ro_compat), 0 },
+ { offsetof(xfs_sb_t, sb_features_incompat), 0 },
+ { offsetof(xfs_sb_t, sb_features_log_incompat), 0 },
+ { offsetof(xfs_sb_t, sb_crc), 0 },
+ { offsetof(xfs_sb_t, sb_pad), 0 },
+ { offsetof(xfs_sb_t, sb_pquotino), 0 },
+ { offsetof(xfs_sb_t, sb_lsn), 0 },
+ { sizeof(xfs_sb_t), 0 }
+};
+
+/*
+ * Reference counting access wrappers to the perag structures.
+ * Because we never free per-ag structures, the only thing we
+ * have to protect against changes is the tree structure itself.
+ */
+struct xfs_perag *
+xfs_perag_get(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agno)
+{
+ struct xfs_perag *pag;
+ int ref = 0;
+
+ rcu_read_lock();
+ pag = radix_tree_lookup(&mp->m_perag_tree, agno);
+ if (pag) {
+ ASSERT(atomic_read(&pag->pag_ref) >= 0);
+ ref = atomic_inc_return(&pag->pag_ref);
+ }
+ rcu_read_unlock();
+ trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
+ return pag;
+}
+
+/*
+ * search from @first to find the next perag with the given tag set.
+ */
+struct xfs_perag *
+xfs_perag_get_tag(
+ struct xfs_mount *mp,
+ xfs_agnumber_t first,
+ int tag)
+{
+ struct xfs_perag *pag;
+ int found;
+ int ref;
+
+ rcu_read_lock();
+ found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
+ (void **)&pag, first, 1, tag);
+ if (found <= 0) {
+ rcu_read_unlock();
+ return NULL;
+ }
+ ref = atomic_inc_return(&pag->pag_ref);
+ rcu_read_unlock();
+ trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_);
+ return pag;
+}
+
+void
+xfs_perag_put(
+ struct xfs_perag *pag)
+{
+ int ref;
+
+ ASSERT(atomic_read(&pag->pag_ref) > 0);
+ ref = atomic_dec_return(&pag->pag_ref);
+ trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
+}
+
+/*
+ * Check the validity of the SB found.
+ */
+STATIC int
+xfs_mount_validate_sb(
+ xfs_mount_t *mp,
+ xfs_sb_t *sbp,
+ bool check_inprogress,
+ bool check_version)
+{
+
+ /*
+ * If the log device and data device have the
+ * same device number, the log is internal.
+ * Consequently, the sb_logstart should be non-zero. If
+ * we have a zero sb_logstart in this case, we may be trying to mount
+ * a volume filesystem in a non-volume manner.
+ */
+ if (sbp->sb_magicnum != XFS_SB_MAGIC) {
+ xfs_warn(mp, "bad magic number");
+ return XFS_ERROR(EWRONGFS);
+ }
+
+
+ if (!xfs_sb_good_version(sbp)) {
+ xfs_warn(mp, "bad version");
+ return XFS_ERROR(EWRONGFS);
+ }
+
+ if ((sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) &&
+ (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
+ XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))) {
+ xfs_notice(mp,
+"Super block has XFS_OQUOTA bits along with XFS_PQUOTA and/or XFS_GQUOTA bits.\n");
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ /*
+ * Version 5 superblock feature mask validation. Reject combinations the
+ * kernel cannot support up front before checking anything else. For
+ * write validation, we don't need to check feature masks.
+ */
+ if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
+ xfs_alert(mp,
+"Version 5 superblock detected. xfsprogs has EXPERIMENTAL support enabled!\n"
+"Use of these features is at your own risk!");
+
+ if (xfs_sb_has_compat_feature(sbp,
+ XFS_SB_FEAT_COMPAT_UNKNOWN)) {
+ xfs_warn(mp,
+"Superblock has unknown compatible features (0x%x) enabled.\n"
+"Using a more recent xfsprogs is recommended.",
+ (sbp->sb_features_compat &
+ XFS_SB_FEAT_COMPAT_UNKNOWN));
+ }
+
+ if (xfs_sb_has_ro_compat_feature(sbp,
+ XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
+ xfs_warn(mp,
+"Superblock has unknown read-only compatible features (0x%x) enabled.\n"
+"Using a more recent xfsprogs is recommended.",
+ (sbp->sb_features_ro_compat &
+ XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
+ }
+ if (xfs_sb_has_incompat_feature(sbp,
+ XFS_SB_FEAT_INCOMPAT_UNKNOWN)) {
+ xfs_warn(mp,
+"Superblock has unknown incompatible features (0x%x) enabled.\n"
+"Filesystem can not be safely operated on by this xfsprogs installation",
+ (sbp->sb_features_incompat &
+ XFS_SB_FEAT_INCOMPAT_UNKNOWN));
+ return XFS_ERROR(EINVAL);
+ }
+ }
+
+ if (unlikely(
+ sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
+ xfs_warn(mp,
+ "filesystem is marked as having an external log; "
+ "specify logdev on the mount command line.");
+ return XFS_ERROR(EINVAL);
+ }
+
+ if (unlikely(
+ sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
+ xfs_warn(mp,
+ "filesystem is marked as having an internal log; "
+ "do not specify logdev on the mount command line.");
+ return XFS_ERROR(EINVAL);
+ }
+
+ /*
+ * More sanity checking. Most of these were stolen directly from
+ * xfs_repair.
+ */
+ if (unlikely(
+ sbp->sb_agcount <= 0 ||
+ sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
+ sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
+ sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
+ sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
+ sbp->sb_sectsize != (1 << sbp->sb_sectlog) ||
+ sbp->sb_blocksize < XFS_MIN_BLOCKSIZE ||
+ sbp->sb_blocksize > XFS_MAX_BLOCKSIZE ||
+ sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
+ sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
+ sbp->sb_blocksize != (1 << sbp->sb_blocklog) ||
+ sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
+ sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
+ sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
+ sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
+ sbp->sb_inodesize != (1 << sbp->sb_inodelog) ||
+ (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
+ (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
+ (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
+ (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
+ sbp->sb_dblocks == 0 ||
+ sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
+ sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) {
+ XFS_CORRUPTION_ERROR("SB sanity check failed",
+ XFS_ERRLEVEL_LOW, mp, sbp);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+
+ /*
+ * Currently only very few inode sizes are supported.
+ */
+ switch (sbp->sb_inodesize) {
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ break;
+ default:
+ xfs_warn(mp, "inode size of %d bytes not supported",
+ sbp->sb_inodesize);
+ return XFS_ERROR(ENOSYS);
+ }
+
+ if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) ||
+ xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
+ xfs_warn(mp,
+ "file system too large to be mounted on this system.");
+ return XFS_ERROR(EFBIG);
+ }
+
+ /*
+ * Version 1 directory format has never worked on Linux.
+ */
+ if (unlikely(!xfs_sb_version_hasdirv2(sbp))) {
+ xfs_warn(mp, "file system using version 1 directory format");
+ return XFS_ERROR(ENOSYS);
+ }
+
+ return 0;
+}
+
+void
+xfs_sb_quota_from_disk(
+ struct xfs_sb *sbp)
+{
+ if (sbp->sb_qflags & XFS_OQUOTA_ENFD) {
+ sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
+ XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
+ }
+ if (sbp->sb_qflags & XFS_OQUOTA_CHKD) {
+ sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
+ XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
+ }
+ sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
+}
+
+void
+xfs_sb_from_disk(
+ struct xfs_sb *to,
+ xfs_dsb_t *from)
+{
+ to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
+ to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
+ to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
+ to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
+ to->sb_rextents = be64_to_cpu(from->sb_rextents);
+ memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
+ to->sb_logstart = be64_to_cpu(from->sb_logstart);
+ to->sb_rootino = be64_to_cpu(from->sb_rootino);
+ to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
+ to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
+ to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
+ to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
+ to->sb_agcount = be32_to_cpu(from->sb_agcount);
+ to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
+ to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
+ to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
+ to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
+ to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
+ to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
+ memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
+ to->sb_blocklog = from->sb_blocklog;
+ to->sb_sectlog = from->sb_sectlog;
+ to->sb_inodelog = from->sb_inodelog;
+ to->sb_inopblog = from->sb_inopblog;
+ to->sb_agblklog = from->sb_agblklog;
+ to->sb_rextslog = from->sb_rextslog;
+ to->sb_inprogress = from->sb_inprogress;
+ to->sb_imax_pct = from->sb_imax_pct;
+ to->sb_icount = be64_to_cpu(from->sb_icount);
+ to->sb_ifree = be64_to_cpu(from->sb_ifree);
+ to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
+ to->sb_frextents = be64_to_cpu(from->sb_frextents);
+ to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
+ to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
+ to->sb_qflags = be16_to_cpu(from->sb_qflags);
+ to->sb_flags = from->sb_flags;
+ to->sb_shared_vn = from->sb_shared_vn;
+ to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
+ to->sb_unit = be32_to_cpu(from->sb_unit);
+ to->sb_width = be32_to_cpu(from->sb_width);
+ to->sb_dirblklog = from->sb_dirblklog;
+ to->sb_logsectlog = from->sb_logsectlog;
+ to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
+ to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
+ to->sb_features2 = be32_to_cpu(from->sb_features2);
+ to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
+ to->sb_features_compat = be32_to_cpu(from->sb_features_compat);
+ to->sb_features_ro_compat = be32_to_cpu(from->sb_features_ro_compat);
+ to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat);
+ to->sb_features_log_incompat =
+ be32_to_cpu(from->sb_features_log_incompat);
+ to->sb_pad = 0;
+ to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
+ to->sb_lsn = be64_to_cpu(from->sb_lsn);
+}
+
+static void
+xfs_sb_quota_to_disk(
+ xfs_dsb_t *to,
+ xfs_sb_t *from,
+ __int64_t *fields)
+{
+ __uint16_t qflags = from->sb_qflags;
+
+ if (*fields & XFS_SB_QFLAGS) {
+ /*
+ * The in-core version of sb_qflags do not have
+ * XFS_OQUOTA_* flags, whereas the on-disk version
+ * does. So, convert incore XFS_{PG}QUOTA_* flags
+ * to on-disk XFS_OQUOTA_* flags.
+ */
+ qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
+ XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
+
+ if (from->sb_qflags &
+ (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
+ qflags |= XFS_OQUOTA_ENFD;
+ if (from->sb_qflags &
+ (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
+ qflags |= XFS_OQUOTA_CHKD;
+ to->sb_qflags = cpu_to_be16(qflags);
+ *fields &= ~XFS_SB_QFLAGS;
+ }
+}
+
+/*
+ * Copy in core superblock to ondisk one.
+ *
+ * The fields argument is mask of superblock fields to copy.
+ */
+void
+xfs_sb_to_disk(
+ xfs_dsb_t *to,
+ xfs_sb_t *from,
+ __int64_t fields)
+{
+ xfs_caddr_t to_ptr = (xfs_caddr_t)to;
+ xfs_caddr_t from_ptr = (xfs_caddr_t)from;
+ xfs_sb_field_t f;
+ int first;
+ int size;
+
+ ASSERT(fields);
+ if (!fields)
+ return;
+
+ xfs_sb_quota_to_disk(to, from, &fields);
+ while (fields) {
+ f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
+ first = xfs_sb_info[f].offset;
+ size = xfs_sb_info[f + 1].offset - first;
+
+ ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
+
+ if (size == 1 || xfs_sb_info[f].type == 1) {
+ memcpy(to_ptr + first, from_ptr + first, size);
+ } else {
+ switch (size) {
+ case 2:
+ *(__be16 *)(to_ptr + first) =
+ cpu_to_be16(*(__u16 *)(from_ptr + first));
+ break;
+ case 4:
+ *(__be32 *)(to_ptr + first) =
+ cpu_to_be32(*(__u32 *)(from_ptr + first));
+ break;
+ case 8:
+ *(__be64 *)(to_ptr + first) =
+ cpu_to_be64(*(__u64 *)(from_ptr + first));
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+
+ fields &= ~(1LL << f);
+ }
+}
+
+static int
+xfs_sb_verify(
+ struct xfs_buf *bp,
+ bool check_version)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_sb sb;
+
+ xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp));
+
+ /*
+ * Only check the in progress field for the primary superblock as
+ * mkfs.xfs doesn't clear it from secondary superblocks.
+ */
+ return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
+ check_version);
+}
+
+/*
+ * If the superblock has the CRC feature bit set or the CRC field is non-null,
+ * check that the CRC is valid. We check the CRC field is non-null because a
+ * single bit error could clear the feature bit and unused parts of the
+ * superblock are supposed to be zero. Hence a non-null crc field indicates that
+ * we've potentially lost a feature bit and we should check it anyway.
+ */
+static void
+xfs_sb_read_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
+ int error;
+
+ /*
+ * open code the version check to avoid needing to convert the entire
+ * superblock from disk order just to check the version number
+ */
+ if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC) &&
+ (((be16_to_cpu(dsb->sb_versionnum) & XFS_SB_VERSION_NUMBITS) ==
+ XFS_SB_VERSION_5) ||
+ dsb->sb_crc != 0)) {
+
+ if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize),
+ offsetof(struct xfs_sb, sb_crc))) {
+ error = EFSCORRUPTED;
+ goto out_error;
+ }
+ }
+ error = xfs_sb_verify(bp, true);
+
+out_error:
+ if (error) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+ xfs_buf_ioerror(bp, error);
+ }
+}
+
+/*
+ * We may be probed for a filesystem match, so we may not want to emit
+ * messages when the superblock buffer is not actually an XFS superblock.
+ * If we find an XFS superblock, the run a normal, noisy mount because we are
+ * really going to mount it and want to know about errors.
+ */
+static void
+xfs_sb_quiet_read_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
+
+
+ if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) {
+ /* XFS filesystem, verify noisily! */
+ xfs_sb_read_verify(bp);
+ return;
+ }
+ /* quietly fail */
+ xfs_buf_ioerror(bp, EWRONGFS);
+}
+
+static void
+xfs_sb_write_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_buf_log_item *bip = bp->b_fspriv;
+ int error;
+
+ error = xfs_sb_verify(bp, false);
+ if (error) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+ xfs_buf_ioerror(bp, error);
+ return;
+ }
+
+ if (!xfs_sb_version_hascrc(&mp->m_sb))
+ return;
+
+ if (bip)
+ XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
+
+ xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
+ offsetof(struct xfs_sb, sb_crc));
+}
+
+const struct xfs_buf_ops xfs_sb_buf_ops = {
+ .verify_read = xfs_sb_read_verify,
+ .verify_write = xfs_sb_write_verify,
+};
+
+const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
+ .verify_read = xfs_sb_quiet_read_verify,
+ .verify_write = xfs_sb_write_verify,
+};
+
+/*
+ * xfs_mount_common
+ *
+ * Mount initialization code establishing various mount
+ * fields from the superblock associated with the given
+ * mount structure
+ */
+void
+xfs_sb_mount_common(
+ struct xfs_mount *mp,
+ struct xfs_sb *sbp)
+{
+ mp->m_agfrotor = mp->m_agirotor = 0;
+ spin_lock_init(&mp->m_agirotor_lock);
+ mp->m_maxagi = mp->m_sb.sb_agcount;
+ mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
+ mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
+ mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
+ mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
+ mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
+ mp->m_blockmask = sbp->sb_blocksize - 1;
+ mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
+ mp->m_blockwmask = mp->m_blockwsize - 1;
+
+ mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
+ mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
+ mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
+ mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2;
+
+ mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
+ mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
+ mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2;
+ mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2;
+
+ mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1);
+ mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
+ mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
+ mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2;
+
+ mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
+ mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
+ sbp->sb_inopblock);
+ mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
+}
+
+/*
+ * xfs_initialize_perag_data
+ *
+ * Read in each per-ag structure so we can count up the number of
+ * allocated inodes, free inodes and used filesystem blocks as this
+ * information is no longer persistent in the superblock. Once we have
+ * this information, write it into the in-core superblock structure.
+ */
+int
+xfs_initialize_perag_data(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agcount)
+{
+ xfs_agnumber_t index;
+ xfs_perag_t *pag;
+ xfs_sb_t *sbp = &mp->m_sb;
+ uint64_t ifree = 0;
+ uint64_t ialloc = 0;
+ uint64_t bfree = 0;
+ uint64_t bfreelst = 0;
+ uint64_t btree = 0;
+ int error;
+
+ for (index = 0; index < agcount; index++) {
+ /*
+ * read the agf, then the agi. This gets us
+ * all the information we need and populates the
+ * per-ag structures for us.
+ */
+ error = xfs_alloc_pagf_init(mp, NULL, index, 0);
+ if (error)
+ return error;
+
+ error = xfs_ialloc_pagi_init(mp, NULL, index);
+ if (error)
+ return error;
+ pag = xfs_perag_get(mp, index);
+ ifree += pag->pagi_freecount;
+ ialloc += pag->pagi_count;
+ bfree += pag->pagf_freeblks;
+ bfreelst += pag->pagf_flcount;
+ btree += pag->pagf_btreeblks;
+ xfs_perag_put(pag);
+ }
+ /*
+ * Overwrite incore superblock counters with just-read data
+ */
+ spin_lock(&mp->m_sb_lock);
+ sbp->sb_ifree = ifree;
+ sbp->sb_icount = ialloc;
+ sbp->sb_fdblocks = bfree + bfreelst + btree;
+ spin_unlock(&mp->m_sb_lock);
+
+ /* Fixup the per-cpu counters as well. */
+ xfs_icsb_reinit_counters(mp);
+
+ return 0;
+}
+
+/*
+ * xfs_mod_sb() can be used to copy arbitrary changes to the
+ * in-core superblock into the superblock buffer to be logged.
+ * It does not provide the higher level of locking that is
+ * needed to protect the in-core superblock from concurrent
+ * access.
+ */
+void
+xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
+{
+ xfs_buf_t *bp;
+ int first;
+ int last;
+ xfs_mount_t *mp;
+ xfs_sb_field_t f;
+
+ ASSERT(fields);
+ if (!fields)
+ return;
+ mp = tp->t_mountp;
+ bp = xfs_trans_getsb(tp, mp, 0);
+ first = sizeof(xfs_sb_t);
+ last = 0;
+
+ /* translate/copy */
+
+ xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
+
+ /* find modified range */
+ f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
+ ASSERT((1LL << f) & XFS_SB_MOD_BITS);
+ last = xfs_sb_info[f + 1].offset - 1;
+
+ f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
+ ASSERT((1LL << f) & XFS_SB_MOD_BITS);
+ first = xfs_sb_info[f].offset;
+
+ xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
+ xfs_trans_log_buf(tp, bp, first, last);
+}
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 32/49] xfs: create xfs_bmap_util.[ch]
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (30 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 31/49] libxfs: switch over to xfs_sb.c and remove xfs_mount.c Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 15:13 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 33/49] xfsprogs: sync minor kernel header differences Dave Chinner
` (17 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There is a bunch of code in xfs_bmap.c that is kernel specific and
not shared with userspace. to minimise the difference between the
kernel and userspace code, shift this unshared code to
xfs_bmap_util.c, and the declarations to xfs_bmap_util.h.
The biggest issue here is xfs_bmap_finish() - userspce has it's own
definition of this function, and so we need to move it out of
xfs_bmap.[ch]. This means several other files need to include
xfs_bmap_util.c as well.
It also introduces and interesting dance for the stack switching
code in xfs_bmapi_allocate(). The stack switching/workqueue code is
actually moved to xfs_bmap_util.c, so that userspace can simply use
a #define in a header file to connect the dots without needing to
know about the stack switch code at all.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_bmap.h | 51 ------------
libxfs/xfs.h | 34 ++++++++
libxfs/xfs_bmap.c | 222 +++--------------------------------------------------
3 files changed, 43 insertions(+), 264 deletions(-)
diff --git a/include/xfs_bmap.h b/include/xfs_bmap.h
index ffa67b1..8b2fe97 100644
--- a/include/xfs_bmap.h
+++ b/include/xfs_bmap.h
@@ -108,38 +108,6 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
}
/*
- * Argument structure for xfs_bmap_alloc.
- */
-typedef struct xfs_bmalloca {
- xfs_fsblock_t *firstblock; /* i/o first block allocated */
- struct xfs_bmap_free *flist; /* bmap freelist */
- struct xfs_trans *tp; /* transaction pointer */
- struct xfs_inode *ip; /* incore inode pointer */
- struct xfs_bmbt_irec prev; /* extent before the new one */
- struct xfs_bmbt_irec got; /* extent after, or delayed */
-
- xfs_fileoff_t offset; /* offset in file filling in */
- xfs_extlen_t length; /* i/o length asked/allocated */
- xfs_fsblock_t blkno; /* starting block of new extent */
-
- struct xfs_btree_cur *cur; /* btree cursor */
- xfs_extnum_t idx; /* current extent index */
- int nallocs;/* number of extents alloc'd */
- int logflags;/* flags for transaction logging */
-
- xfs_extlen_t total; /* total blocks needed for xaction */
- xfs_extlen_t minlen; /* minimum allocation size (blocks) */
- xfs_extlen_t minleft; /* amount must be left after alloc */
- char eof; /* set if allocating past last extent */
- char wasdel; /* replacing a delayed allocation */
- char userdata;/* set if is user data */
- char aeof; /* allocated space at eof */
- char conv; /* overwriting unwritten extents */
- int flags;
- int stack_switch;
-} xfs_bmalloca_t;
-
-/*
* Flags for xfs_bmap_add_extent*.
*/
#define BMAP_LEFT_CONTIG (1 << 0)
@@ -202,23 +170,4 @@ int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx,
xfs_extnum_t num);
uint xfs_default_attroffset(struct xfs_inode *ip);
-#ifdef __KERNEL__
-/* bmap to userspace formatter - copy to user & advance pointer */
-typedef int (*xfs_bmap_format_t)(void **, struct getbmapx *, int *);
-
-int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist,
- int *committed);
-int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv,
- xfs_bmap_format_t formatter, void *arg);
-int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff,
- int whichfork, int *eof);
-int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
- int whichfork, int *count);
-int xfs_bmap_punch_delalloc_range(struct xfs_inode *ip,
- xfs_fileoff_t start_fsb, xfs_fileoff_t length);
-
-xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb);
-
-#endif /* __KERNEL__ */
-
#endif /* __XFS_BMAP_H__ */
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 0113b50..276fc25 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -51,6 +51,40 @@
typedef __uint32_t uint_t;
typedef __uint32_t inst_t; /* an instruction */
+/*
+ * Argument structure for xfs_bmap_alloc.
+ */
+typedef struct xfs_bmalloca {
+ xfs_fsblock_t *firstblock; /* i/o first block allocated */
+ struct xfs_bmap_free *flist; /* bmap freelist */
+ struct xfs_trans *tp; /* transaction pointer */
+ struct xfs_inode *ip; /* incore inode pointer */
+ struct xfs_bmbt_irec prev; /* extent before the new one */
+ struct xfs_bmbt_irec got; /* extent after, or delayed */
+
+ xfs_fileoff_t offset; /* offset in file filling in */
+ xfs_extlen_t length; /* i/o length asked/allocated */
+ xfs_fsblock_t blkno; /* starting block of new extent */
+
+ struct xfs_btree_cur *cur; /* btree cursor */
+ xfs_extnum_t idx; /* current extent index */
+ int nallocs;/* number of extents alloc'd */
+ int logflags;/* flags for transaction logging */
+
+ xfs_extlen_t total; /* total blocks needed for xaction */
+ xfs_extlen_t minlen; /* minimum allocation size (blocks) */
+ xfs_extlen_t minleft; /* amount must be left after alloc */
+ char eof; /* set if allocating past last extent */
+ char wasdel; /* replacing a delayed allocation */
+ char userdata;/* set if is user data */
+ char aeof; /* allocated space at eof */
+ char conv; /* overwriting unwritten extents */
+ char stack_switch;
+ int flags;
+} xfs_bmalloca_t;
+
+#define xfs_bmapi_allocate __xfs_bmapi_allocate
+
#ifndef EWRONGFS
#define EWRONGFS EINVAL
#endif
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index ce72b87..eeaea94 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -74,19 +74,6 @@ xfs_bmap_compute_maxlevels(
mp->m_bm_maxlevels[whichfork] = level;
}
-/*
- * Convert the given file system block to a disk block. We have to treat it
- * differently based on whether the file is a real time file or not, because the
- * bmap code does.
- */
-xfs_daddr_t
-xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
-{
- return (XFS_IS_REALTIME_INODE(ip) ? \
- (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
-}
-
STATIC int /* error */
xfs_bmbt_lookup_eq(
struct xfs_btree_cur *cur,
@@ -229,173 +216,6 @@ xfs_bmap_forkoff_reset(
}
/*
- * Extent tree block counting routines.
- */
-
-/*
- * Count leaf blocks given a range of extent records.
- */
-STATIC void
-xfs_bmap_count_leaves(
- xfs_ifork_t *ifp,
- xfs_extnum_t idx,
- int numrecs,
- int *count)
-{
- int b;
-
- for (b = 0; b < numrecs; b++) {
- xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
- *count += xfs_bmbt_get_blockcount(frp);
- }
-}
-
-/*
- * Count leaf blocks given a range of extent records originally
- * in btree format.
- */
-STATIC void
-xfs_bmap_disk_count_leaves(
- struct xfs_mount *mp,
- struct xfs_btree_block *block,
- int numrecs,
- int *count)
-{
- int b;
- xfs_bmbt_rec_t *frp;
-
- for (b = 1; b <= numrecs; b++) {
- frp = XFS_BMBT_REC_ADDR(mp, block, b);
- *count += xfs_bmbt_disk_get_blockcount(frp);
- }
-}
-
-/*
- * Recursively walks each level of a btree
- * to count total fsblocks is use.
- */
-STATIC int /* error */
-xfs_bmap_count_tree(
- xfs_mount_t *mp, /* file system mount point */
- xfs_trans_t *tp, /* transaction pointer */
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fsblock_t blockno, /* file system block number */
- int levelin, /* level in btree */
- int *count) /* Count of blocks */
-{
- int error;
- xfs_buf_t *bp, *nbp;
- int level = levelin;
- __be64 *pp;
- xfs_fsblock_t bno = blockno;
- xfs_fsblock_t nextbno;
- struct xfs_btree_block *block, *nextblock;
- int numrecs;
-
- error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
- if (error)
- return error;
- *count += 1;
- block = XFS_BUF_TO_BLOCK(bp);
-
- if (--level) {
- /* Not at node above leaves, count this level of nodes */
- nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
- while (nextbno != NULLFSBLOCK) {
- error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp,
- XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
- if (error)
- return error;
- *count += 1;
- nextblock = XFS_BUF_TO_BLOCK(nbp);
- nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib);
- xfs_trans_brelse(tp, nbp);
- }
-
- /* Dive to the next level */
- pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
- bno = be64_to_cpu(*pp);
- if (unlikely((error =
- xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
- xfs_trans_brelse(tp, bp);
- XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
- XFS_ERRLEVEL_LOW, mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- xfs_trans_brelse(tp, bp);
- } else {
- /* count all level 1 nodes and their leaves */
- for (;;) {
- nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
- numrecs = be16_to_cpu(block->bb_numrecs);
- xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
- xfs_trans_brelse(tp, bp);
- if (nextbno == NULLFSBLOCK)
- break;
- bno = nextbno;
- error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
- XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
- if (error)
- return error;
- *count += 1;
- block = XFS_BUF_TO_BLOCK(bp);
- }
- }
- return 0;
-}
-
-/*
- * Count fsblocks of the given fork.
- */
-int /* error */
-xfs_bmap_count_blocks(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- int whichfork, /* data or attr fork */
- int *count) /* out: count of blocks */
-{
- struct xfs_btree_block *block; /* current btree block */
- xfs_fsblock_t bno; /* block # of "block" */
- xfs_ifork_t *ifp; /* fork structure */
- int level; /* btree level, for checking */
- xfs_mount_t *mp; /* file system mount structure */
- __be64 *pp; /* pointer to block address */
-
- bno = NULLFSBLOCK;
- mp = ip->i_mount;
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
- xfs_bmap_count_leaves(ifp, 0,
- ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
- count);
- return 0;
- }
-
- /*
- * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
- */
- block = ifp->if_broot;
- level = be16_to_cpu(block->bb_level);
- ASSERT(level > 0);
- pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
- bno = be64_to_cpu(*pp);
- ASSERT(bno != NULLDFSBNO);
- ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
- ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
-
- if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
- XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
- mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
-
- return 0;
-}
-
-/*
* Debug/sanity checking code
*/
@@ -803,7 +623,6 @@ xfs_bmap_del_free(
kmem_zone_free(xfs_bmap_free_item_zone, free);
}
-
/*
* Free up any items left in the list.
*/
@@ -1028,8 +847,8 @@ xfs_bmap_extents_to_btree(
* Do all this logging at the end so that
* the root is at the right level.
*/
- xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
+ xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
ASSERT(*curp == NULL);
*curp = cur;
*logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
@@ -1744,7 +1563,7 @@ xfs_bmap_last_before(
return 0;
}
-STATIC int
+int
xfs_bmap_last_extent(
struct xfs_trans *tp,
struct xfs_inode *ip,
@@ -1808,29 +1627,6 @@ xfs_bmap_isaeof(
}
/*
- * Check if the endoff is outside the last extent. If so the caller will grow
- * the allocation to a stripe unit boundary. All offsets are considered outside
- * the end of file for an empty fork, so 1 is returned in *eof in that case.
- */
-int
-xfs_bmap_eof(
- struct xfs_inode *ip,
- xfs_fileoff_t endoff,
- int whichfork,
- int *eof)
-{
- struct xfs_bmbt_irec rec;
- int error;
-
- error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, eof);
- if (error || *eof)
- return error;
-
- *eof = endoff >= rec.br_startoff + rec.br_blockcount;
- return 0;
-}
-
-/*
* Returns the file-relative block number of the first block past eof in
* the file. This is not based on i_size, it is based on the extent records.
* Returns 0 for local files, as they do not have extent records.
@@ -3369,7 +3165,7 @@ done:
/*
* Adjust the size of the new extent based on di_extsize and rt extsize.
*/
-STATIC int
+int
xfs_bmap_extsize_align(
xfs_mount_t *mp,
xfs_bmbt_irec_t *gotp, /* next extent pointer */
@@ -3531,9 +3327,9 @@ xfs_bmap_extsize_align(
#define XFS_ALLOC_GAP_UNITS 4
-STATIC void
+void
xfs_bmap_adjacent(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
+ struct xfs_bmalloca *ap) /* bmap alloc argument struct */
{
xfs_fsblock_t adjust; /* adjustment to block numbers */
xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
@@ -3796,7 +3592,7 @@ xfs_bmap_btalloc_nullfb(
STATIC int
xfs_bmap_btalloc(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
+ struct xfs_bmalloca *ap) /* bmap alloc argument struct */
{
xfs_mount_t *mp; /* mount point structure */
xfs_alloctype_t atype = 0; /* type for allocation routines */
@@ -4028,7 +3824,7 @@ xfs_bmap_btalloc(
*/
STATIC int
xfs_bmap_alloc(
- xfs_bmalloca_t *ap) /* bmap alloc argument struct */
+ struct xfs_bmalloca *ap) /* bmap alloc argument struct */
{
if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata)
return xfs_bmap_rtalloc(ap);
@@ -4416,8 +4212,8 @@ xfs_bmapi_delay(
}
-STATIC int
-xfs_bmapi_allocate(
+int
+__xfs_bmapi_allocate(
struct xfs_bmalloca *bma)
{
struct xfs_mount *mp = bma->ip->i_mount;
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 33/49] xfsprogs: sync minor kernel header differences
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (31 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 32/49] xfs: create xfs_bmap_util.[ch] Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 15:26 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 34/49] xfs: don't special case shared superblock mounts Dave Chinner
` (16 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There are lots of little differences between kernel and userspace
headers noticable now that the files are largely the same. Clean up
all the formatting, whitespace and other minor differences in the
userspace headers.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 8 +++++---
include/xfs_ag.h | 2 +-
include/xfs_alloc_btree.h | 3 +--
include/xfs_attr_remote.h | 28 +++++++++++-----------------
include/xfs_bmap_btree.h | 3 +--
include/xfs_btree.h | 3 +--
include/xfs_dinode.h | 3 ---
include/xfs_dir2.h | 11 +----------
include/xfs_dir2_format.h | 22 ++++++++++++++--------
include/xfs_fs.h | 26 +++++++++++++++-----------
include/xfs_ialloc_btree.h | 3 +--
include/xfs_inode_buf.h | 1 -
include/xfs_trans.h | 8 +++-----
libxfs/xfs.h | 2 ++
14 files changed, 56 insertions(+), 67 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index b4d2657..d3b3f02 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -46,7 +46,6 @@
#include <xfs/xfs_inum.h>
#include <xfs/xfs_sb.h>
#include <xfs/xfs_ag.h>
-#include <xfs/xfs_dir2.h>
#include <xfs/xfs_da_btree.h>
#include <xfs/xfs_bmap_btree.h>
#include <xfs/xfs_alloc_btree.h>
@@ -235,6 +234,11 @@ extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *,
extern void libxfs_umount (xfs_mount_t *);
extern void libxfs_rtmount_destroy (xfs_mount_t *);
+/*
+ * xfs/xfs_dir2_format.h needs struct xfs_mount to be defined
+ */
+#include <xfs/xfs_dir2_format.h>
+#include <xfs/xfs_dir2.h>
/*
* Simple I/O interface
@@ -610,8 +614,6 @@ extern int libxfs_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t,
uint, xfs_inode_t **, xfs_daddr_t);
extern void libxfs_iput (xfs_inode_t *, uint);
-#include <xfs/xfs_dir2_format.h>
-
/* Shared utility routines */
extern unsigned int libxfs_log2_roundup(unsigned int i);
diff --git a/include/xfs_ag.h b/include/xfs_ag.h
index 1e0fa34..317aa86 100644
--- a/include/xfs_ag.h
+++ b/include/xfs_ag.h
@@ -102,7 +102,7 @@ typedef struct xfs_agf {
#define XFS_AGF_LONGEST 0x00000400
#define XFS_AGF_BTREEBLKS 0x00000800
#define XFS_AGF_UUID 0x00001000
-#define XFS_AGF_NUM_BITS 12
+#define XFS_AGF_NUM_BITS 13
#define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1)
#define XFS_AGF_FLAGS \
diff --git a/include/xfs_alloc_btree.h b/include/xfs_alloc_btree.h
index e160339..e3a3f74 100644
--- a/include/xfs_alloc_btree.h
+++ b/include/xfs_alloc_btree.h
@@ -64,8 +64,7 @@ typedef __be32 xfs_alloc_ptr_t;
*/
#define XFS_ALLOC_BLOCK_LEN(mp) \
(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
- XFS_BTREE_SBLOCK_CRC_LEN : \
- XFS_BTREE_SBLOCK_LEN)
+ XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN)
/*
* Record, key, and pointer address macros for btree blocks.
diff --git a/include/xfs_attr_remote.h b/include/xfs_attr_remote.h
index d087305..92a8fd7 100644
--- a/include/xfs_attr_remote.h
+++ b/include/xfs_attr_remote.h
@@ -1,25 +1,19 @@
/*
* Copyright (c) 2013 Red Hat, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
- * USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ATTR_REMOTE_H__
#define __XFS_ATTR_REMOTE_H__
diff --git a/include/xfs_bmap_btree.h b/include/xfs_bmap_btree.h
index f1069bb..1b726d6 100644
--- a/include/xfs_bmap_btree.h
+++ b/include/xfs_bmap_btree.h
@@ -140,8 +140,7 @@ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
*/
#define XFS_BMBT_BLOCK_LEN(mp) \
(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
- XFS_BTREE_LBLOCK_CRC_LEN : \
- XFS_BTREE_LBLOCK_LEN)
+ XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN)
#define XFS_BMBT_REC_ADDR(mp, block, index) \
((xfs_bmbt_rec_t *) \
diff --git a/include/xfs_btree.h b/include/xfs_btree.h
index c0acbbf..b55af99 100644
--- a/include/xfs_btree.h
+++ b/include/xfs_btree.h
@@ -93,7 +93,6 @@ struct xfs_btree_block {
#define XFS_BTREE_LBLOCK_CRC_OFF \
offsetof(struct xfs_btree_block, bb_u.l.bb_crc)
-
/*
* Generic key, ptr and record wrapper structures.
*
@@ -214,7 +213,7 @@ struct xfs_btree_ops {
const struct xfs_buf_ops *buf_ops;
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
/* check that k1 is lower than k2 */
int (*keys_inorder)(struct xfs_btree_cur *cur,
union xfs_btree_key *k1,
diff --git a/include/xfs_dinode.h b/include/xfs_dinode.h
index f7a0e95..07d735a 100644
--- a/include/xfs_dinode.h
+++ b/include/xfs_dinode.h
@@ -132,9 +132,6 @@ typedef enum xfs_dinode_fmt {
#define XFS_LITINO(mp, version) \
((int)(((mp)->m_sb.sb_inodesize) - xfs_dinode_size(version)))
-#define XFS_BROOT_SIZE_ADJ(ip) \
- (XFS_BMBT_BLOCK_LEN((ip)->i_mount) - sizeof(xfs_bmdr_block_t))
-
/*
* Inode data & attribute fork sizes, per inode.
*/
diff --git a/include/xfs_dir2.h b/include/xfs_dir2.h
index 75e8596..7fe2b8f 100644
--- a/include/xfs_dir2.h
+++ b/include/xfs_dir2.h
@@ -28,14 +28,6 @@ struct xfs_dir2_sf_entry;
struct xfs_dir2_data_hdr;
struct xfs_dir2_data_entry;
struct xfs_dir2_data_unused;
-struct xfs_dir2_data_free;
-
-typedef uint xfs_dir2_data_aoff_t; /* argument form */
-
-/*
- * Directory block number (logical dirblk in file)
- */
-typedef __uint32_t xfs_dir2_db_t;
extern struct xfs_name xfs_name_dotdot;
@@ -71,7 +63,7 @@ extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
/*
- * used by db
+ * Interface routines used by userspace utilities
*/
extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
extern void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *sfp,
@@ -110,5 +102,4 @@ extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
-
#endif /* __XFS_DIR2_H__ */
diff --git a/include/xfs_dir2_format.h b/include/xfs_dir2_format.h
index 4126e86..2095e17 100644
--- a/include/xfs_dir2_format.h
+++ b/include/xfs_dir2_format.h
@@ -73,6 +73,7 @@
*/
typedef __uint16_t xfs_dir2_data_off_t;
#define NULLDATAOFF 0xffffU
+typedef uint xfs_dir2_data_aoff_t; /* argument form */
/*
* Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
@@ -93,6 +94,11 @@ typedef __uint32_t xfs_dir2_dataptr_t;
typedef xfs_off_t xfs_dir2_off_t;
/*
+ * Directory block number (logical dirblk in file)
+ */
+typedef __uint32_t xfs_dir2_db_t;
+
+/*
* Inode number stored as 8 8-bit values.
*/
typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
@@ -144,19 +150,19 @@ static inline int xfs_dir2_sf_hdr_size(int i8count)
(sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
}
- static inline xfs_dir2_data_aoff_t
+static inline xfs_dir2_data_aoff_t
xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
{
return get_unaligned_be16(&sfep->offset.i);
}
- static inline void
+static inline void
xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
{
put_unaligned_be16(off, &sfep->offset.i);
}
- static inline int
+static inline int
xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
{
return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
@@ -166,14 +172,14 @@ xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
sizeof(xfs_dir2_ino4_t));
}
- static inline struct xfs_dir2_sf_entry *
+static inline struct xfs_dir2_sf_entry *
xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
{
return (struct xfs_dir2_sf_entry *)
((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
}
- static inline struct xfs_dir2_sf_entry *
+static inline struct xfs_dir2_sf_entry *
xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
struct xfs_dir2_sf_entry *sfep)
{
@@ -238,7 +244,7 @@ typedef struct xfs_dir2_data_free {
*/
typedef struct xfs_dir2_data_hdr {
__be32 magic; /* XFS_DIR2_DATA_MAGIC or */
- /* XFS_DIR2_BLOCK_MAGIC */
+ /* XFS_DIR2_BLOCK_MAGIC */
xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
} xfs_dir2_data_hdr_t;
@@ -265,7 +271,7 @@ struct xfs_dir3_data_hdr {
#define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc)
- static inline struct xfs_dir2_data_free *
+static inline struct xfs_dir2_data_free *
xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
{
if (hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -514,7 +520,7 @@ struct xfs_dir3_leaf {
#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to,
- struct xfs_dir2_leaf *from);
+ struct xfs_dir2_leaf *from);
static inline int
xfs_dir3_leaf_hdr_size(struct xfs_dir2_leaf *lp)
diff --git a/include/xfs_fs.h b/include/xfs_fs.h
index 44b69e7..68c2e18 100644
--- a/include/xfs_fs.h
+++ b/include/xfs_fs.h
@@ -311,6 +311,17 @@ typedef struct xfs_bstat {
} xfs_bstat_t;
/*
+ * Project quota id helpers (previously projid was 16bit only
+ * and using two 16bit values to hold new 32bit projid was choosen
+ * to retain compatibility with "old" filesystems).
+ */
+static inline __uint32_t
+bstat_get_projid(struct xfs_bstat *bs)
+{
+ return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo;
+}
+
+/*
* The user-level BulkStat Request interface structure.
*/
typedef struct xfs_fsop_bulkreq {
@@ -511,10 +522,14 @@ typedef struct xfs_handle {
#define XFS_IOC_ERROR_INJECTION _IOW ('X', 116, struct xfs_error_injection)
#define XFS_IOC_ERROR_CLEARALL _IOW ('X', 117, struct xfs_error_injection)
/* XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118 */
+
/* XFS_IOC_FREEZE -- FIFREEZE 119 */
/* XFS_IOC_THAW -- FITHAW 120 */
+#ifndef FIFREEZE
#define XFS_IOC_FREEZE _IOWR('X', 119, int)
#define XFS_IOC_THAW _IOWR('X', 120, int)
+#endif
+
#define XFS_IOC_FSSETDM_BY_HANDLE _IOW ('X', 121, struct xfs_fsop_setdm_handlereq)
#define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq)
#define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)
@@ -537,15 +552,4 @@ typedef struct xfs_handle {
#define BBTOB(bbs) ((bbs) << BBSHIFT)
#endif
-/*
- * Project quota id helpers (previously projid was 16bit only
- * and using two 16bit values to hold new 32bit projid was choosen
- * to retain compatibility with "old" filesystems).
- */
-static inline __uint32_t
-bstat_get_projid(struct xfs_bstat *bs)
-{
- return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo;
-}
-
#endif /* __XFS_FS_H__ */
diff --git a/include/xfs_ialloc_btree.h b/include/xfs_ialloc_btree.h
index 7f5ae6b..3ac36b7 100644
--- a/include/xfs_ialloc_btree.h
+++ b/include/xfs_ialloc_btree.h
@@ -80,8 +80,7 @@ typedef __be32 xfs_inobt_ptr_t;
*/
#define XFS_INOBT_BLOCK_LEN(mp) \
(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
- XFS_BTREE_SBLOCK_CRC_LEN : \
- XFS_BTREE_SBLOCK_LEN)
+ XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN)
/*
* Record, key, and pointer address macros for btree blocks.
diff --git a/include/xfs_inode_buf.h b/include/xfs_inode_buf.h
index b5f1e22..aae9fc4 100644
--- a/include/xfs_inode_buf.h
+++ b/include/xfs_inode_buf.h
@@ -40,7 +40,6 @@ int xfs_iread(struct xfs_mount *, struct xfs_trans *,
void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
void xfs_dinode_to_disk(struct xfs_dinode *,
struct xfs_icdinode *);
-bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
#if defined(DEBUG)
void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index 37aca08..8e67284 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -200,7 +200,7 @@ typedef struct xfs_trans {
int64_t t_res_fdblocks_delta; /* on-disk only chg */
int64_t t_frextents_delta;/* superblock freextents chg*/
int64_t t_res_frextents_delta; /* on-disk only chg */
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
int64_t t_ag_freeblks_delta; /* debugging counter */
int64_t t_ag_flist_delta; /* debugging counter */
int64_t t_ag_btree_delta; /* debugging counter */
@@ -228,7 +228,7 @@ typedef struct xfs_trans {
#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d)
#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d)
#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d)
@@ -298,6 +298,7 @@ void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
+void xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
@@ -327,7 +328,4 @@ extern kmem_zone_t *xfs_log_item_desc_zone;
#endif /* __KERNEL__ */
-void xfs_trans_init(struct xfs_mount *);
-int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *);
-
#endif /* __XFS_TRANS_H__ */
diff --git a/libxfs/xfs.h b/libxfs/xfs.h
index 276fc25..0ab5f21 100644
--- a/libxfs/xfs.h
+++ b/libxfs/xfs.h
@@ -437,3 +437,5 @@ xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, struct xfs_buftarg *,
/* local source files */
int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
void xfs_trans_mod_sb(xfs_trans_t *, uint, long);
+void xfs_trans_init(struct xfs_mount *);
+int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *);
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 34/49] xfs: don't special case shared superblock mounts
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (32 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 33/49] xfsprogs: sync minor kernel header differences Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 15:33 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops Dave Chinner
` (15 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Neither kernel or userspace support shared read-only mounts, so
don't beother special casing the support check to be different
between kernel and userspace. The same check canbe used as neither
like it...
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_sb.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index dea0373..d6f3648 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -355,15 +355,8 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
(sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS)))
return 0;
-#ifdef __KERNEL__
if (sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN)
return 0;
-#else
- if ((sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) &&
- sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN)
- return 0;
-#endif
-
return 1;
}
if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (33 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 34/49] xfs: don't special case shared superblock mounts Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 15:41 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code Dave Chinner
` (14 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Swapping extents is clearly an extent operaiton, and it is not
shared with userspace. Move the code to xfs_extent_ops.[ch], and
the userspace ioctl structure definition to xfs_fs.h where most of
the other ioctl structure definitions are. The means xfs_dfrag.h is
no longer needed in userspace.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fsr/xfs_fsr.c | 1 -
include/Makefile | 3 +--
include/xfs_dfrag.h | 53 -----------------------------------------------------
include/xfs_fs.h | 15 +++++++++++++++
4 files changed, 16 insertions(+), 56 deletions(-)
delete mode 100644 include/xfs_dfrag.h
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 7e518c1..7596834 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -20,7 +20,6 @@
#include <xfs/xfs.h>
#include <xfs/xfs_types.h>
#include <xfs/jdm.h>
-#include <xfs/xfs_dfrag.h>
#include <xfs/xfs_bmap_btree.h>
#include <xfs/xfs_dinode.h>
#include <xfs/xfs_attr_sf.h>
diff --git a/include/Makefile b/include/Makefile
index 53821ee..5090900 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -41,8 +41,7 @@ QAHFILES = libxfs.h libxlog.h \
xfs_trace.h \
xfs_trans.h \
xfs_trans_resv.h \
- xfs_trans_space.h \
- xfs_dfrag.h
+ xfs_trans_space.h
HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h xfs_types.h
HFILES += $(PKG_PLATFORM).h
diff --git a/include/xfs_dfrag.h b/include/xfs_dfrag.h
deleted file mode 100644
index 20bdd93..0000000
--- a/include/xfs_dfrag.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2000,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DFRAG_H__
-#define __XFS_DFRAG_H__
-
-/*
- * Structure passed to xfs_swapext
- */
-
-typedef struct xfs_swapext
-{
- __int64_t sx_version; /* version */
- __int64_t sx_fdtarget; /* fd of target file */
- __int64_t sx_fdtmp; /* fd of tmp file */
- xfs_off_t sx_offset; /* offset into file */
- xfs_off_t sx_length; /* leng from offset */
- char sx_pad[16]; /* pad space, unused */
- xfs_bstat_t sx_stat; /* stat of target b4 copy */
-} xfs_swapext_t;
-
-/*
- * Version flag
- */
-#define XFS_SX_VERSION 0
-
-#ifdef __KERNEL__
-/*
- * Prototypes for visible xfs_dfrag.c routines.
- */
-
-/*
- * Syscall interface for xfs_swapext
- */
-int xfs_swapext(struct xfs_swapext *sx);
-
-#endif /* __KERNEL__ */
-
-#endif /* __XFS_DFRAG_H__ */
diff --git a/include/xfs_fs.h b/include/xfs_fs.h
index 68c2e18..74b24b2 100644
--- a/include/xfs_fs.h
+++ b/include/xfs_fs.h
@@ -461,6 +461,21 @@ typedef struct xfs_handle {
+ (handle).ha_fid.fid_len)
/*
+ * Structure passed to XFS_IOC_SWAPEXT
+ */
+typedef struct xfs_swapext
+{
+ __int64_t sx_version; /* version */
+#define XFS_SX_VERSION 0
+ __int64_t sx_fdtarget; /* fd of target file */
+ __int64_t sx_fdtmp; /* fd of tmp file */
+ xfs_off_t sx_offset; /* offset into file */
+ xfs_off_t sx_length; /* leng from offset */
+ char sx_pad[16]; /* pad space, unused */
+ xfs_bstat_t sx_stat; /* stat of target b4 copy */
+} xfs_swapext_t;
+
+/*
* Flags for going down operation
*/
#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (34 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 15:52 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 37/49] xfs: remove __KERNEL__ from debug code Dave Chinner
` (13 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Userspace running debug builds is relatively rare, so there's need
to special case the allocation algorithm code coverage debug switch.
As it is, userspace defines random numbers to 0, so invert the
logic of the switch so it is effectively a no-op in userspace.
This kills another couple of __KERNEL__ users.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_alloc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 757b43d..e4fb1ad 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -856,7 +856,7 @@ xfs_alloc_ag_vextent_near(
xfs_agblock_t ltnew; /* useful start bno of left side */
xfs_extlen_t rlen; /* length of returned extent */
int forced = 0;
-#if defined(DEBUG) && defined(__KERNEL__)
+#ifdef DEBUG
/*
* Randomly don't execute the first algorithm.
*/
@@ -916,8 +916,8 @@ restart:
xfs_extlen_t blen=0;
xfs_agblock_t bnew=0;
-#if defined(DEBUG) && defined(__KERNEL__)
- if (!dofirst)
+#ifdef DEBUG
+ if (dofirst)
break;
#endif
/*
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 37/49] xfs: remove __KERNEL__ from debug code
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (35 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 16:07 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c Dave Chinner
` (12 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
There is no reason the remaining kernel-only debug code needs to
remain kernel-only. Kill the __KERNEL__ part of the defines, and let
userspace handle the debug code appropriately.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_bmap.h | 2 +-
libxfs/xfs_dir2_data.c | 4 ++--
libxfs/xfs_rtalloc.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/xfs_bmap.h b/include/xfs_bmap.h
index 8b2fe97..33b41f3 100644
--- a/include/xfs_bmap.h
+++ b/include/xfs_bmap.h
@@ -127,7 +127,7 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
{ BMAP_RIGHT_FILLING, "RF" }, \
{ BMAP_ATTRFORK, "ATTR" }
-#if defined(__KERNEL) && defined(DEBUG)
+#ifdef DEBUG
void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,
int whichfork, unsigned long caller_ip);
#define XFS_BMAP_TRACE_EXLIST(ip,c,w) \
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index 064ddb2..5074878 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -315,7 +315,7 @@ xfs_dir2_data_freefind(
xfs_dir2_data_free_t *dfp; /* bestfree entry */
xfs_dir2_data_aoff_t off; /* offset value needed */
struct xfs_dir2_data_free *bf;
-#if defined(DEBUG) && defined(__KERNEL__)
+#ifdef DEBUG
int matched; /* matched the value */
int seenzero; /* saw a 0 bestfree entry */
#endif
@@ -323,7 +323,7 @@ xfs_dir2_data_freefind(
off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
bf = xfs_dir3_data_bestfree_p(hdr);
-#if defined(DEBUG) && defined(__KERNEL__)
+#ifdef DEBUG
/*
* Validate some consistency in the bestfree table.
* Check order, non-overlapping entries, and if we find the
diff --git a/libxfs/xfs_rtalloc.c b/libxfs/xfs_rtalloc.c
index 9797db7..f5a90b2 100644
--- a/libxfs/xfs_rtalloc.c
+++ b/libxfs/xfs_rtalloc.c
@@ -735,7 +735,7 @@ xfs_rtfree_extent(
ASSERT(mp->m_rbmip->i_itemp != NULL);
ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
-#if defined(__KERNEL__) && defined(DEBUG)
+#ifdef DEBUG
/*
* Check to see that this whole range is currently allocated.
*/
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (36 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 37/49] xfs: remove __KERNEL__ from debug code Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 16:12 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h Dave Chinner
` (11 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
It's actually an ifndef section, which means it is only included in
userspace. however, it's deep within the libxfs code, so it's
unlikely that the condition checked in userspace can actually occur
(search an empty leaf) through the libxfs interfaces. i.e. if it can
happen in usrspace, it can happen in the kernel, so remove it from
userspace too....
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
libxfs/xfs_dir2_leaf.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index 8c20b9e..55b7d05 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -1568,10 +1568,6 @@ xfs_dir2_leaf_search_hash(
ents = xfs_dir3_leaf_ents_p(leaf);
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
-#ifndef __KERNEL__
- if (!leafhdr.count)
- return 0;
-#endif
/*
* Note, the table cannot be empty, so we have to go through the loop.
* Binary search the leaf entries looking for our hash value.
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (37 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 16:16 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 40/49] xfs: make struct xfs_perag kernel only Dave Chinner
` (10 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
xfs_types.h is shared with userspace, so having kernel specific
types defined in it is problematic. Move all the kernel specific
defines to xfs_linux.h so we can remove the __KERNEL__ guards from
xfs_types.h
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_types.h | 36 ------------------------------------
1 file changed, 36 deletions(-)
diff --git a/include/xfs_types.h b/include/xfs_types.h
index 6ed6b26..ce44b18 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -18,42 +18,6 @@
#ifndef __XFS_TYPES_H__
#define __XFS_TYPES_H__
-#ifdef __KERNEL__
-
-/*
- * Additional type declarations for XFS
- */
-typedef signed char __int8_t;
-typedef unsigned char __uint8_t;
-typedef signed short int __int16_t;
-typedef unsigned short int __uint16_t;
-typedef signed int __int32_t;
-typedef unsigned int __uint32_t;
-typedef signed long long int __int64_t;
-typedef unsigned long long int __uint64_t;
-
-typedef __uint32_t inst_t; /* an instruction */
-
-typedef __s64 xfs_off_t; /* <file offset> type */
-typedef unsigned long long xfs_ino_t; /* <inode> type */
-typedef __s64 xfs_daddr_t; /* <disk address> type */
-typedef char * xfs_caddr_t; /* <core address> type */
-typedef __u32 xfs_dev_t;
-typedef __u32 xfs_nlink_t;
-
-/* __psint_t is the same size as a pointer */
-#if (BITS_PER_LONG == 32)
-typedef __int32_t __psint_t;
-typedef __uint32_t __psunsigned_t;
-#elif (BITS_PER_LONG == 64)
-typedef __int64_t __psint_t;
-typedef __uint64_t __psunsigned_t;
-#else
-#error BITS_PER_LONG must be 32 or 64
-#endif
-
-#endif /* __KERNEL__ */
-
typedef __uint32_t prid_t; /* project ID */
typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 40/49] xfs: make struct xfs_perag kernel only
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (38 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 16:28 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items Dave Chinner
` (9 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The struct xfs_perag has many kernel-only definitions in it,
requiring a __KERNEL__ guard so userspace can use it to. Move it to
xfs_mount.h so that it it kernel-only, and let userspace redefine
it's own version of the structure containing only what it needs.
This gets rid of another __KERNEL__ check in the XFS header files.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 31 +++++++++++++++++++++++++++++++
include/xfs_ag.h | 53 -----------------------------------------------------
2 files changed, 31 insertions(+), 53 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index d3b3f02..03caf9c 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -218,6 +218,37 @@ typedef struct xfs_mount {
xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
} xfs_mount_t;
+/*
+ * Per-ag incore structure, copies of information in agf and agi,
+ * to improve the performance of allocation group selection.
+ */
+typedef struct xfs_perag {
+ struct xfs_mount *pag_mount; /* owner filesystem */
+ xfs_agnumber_t pag_agno; /* AG this structure belongs to */
+ atomic_t pag_ref; /* perag reference count */
+ char pagf_init; /* this agf's entry is initialized */
+ char pagi_init; /* this agi's entry is initialized */
+ char pagf_metadata; /* the agf is preferred to be metadata */
+ char pagi_inodeok; /* The agi is ok for inodes */
+ __uint8_t pagf_levels[XFS_BTNUM_AGF];
+ /* # of levels in bno & cnt btree */
+ __uint32_t pagf_flcount; /* count of blocks in freelist */
+ xfs_extlen_t pagf_freeblks; /* total free blocks */
+ xfs_extlen_t pagf_longest; /* longest free space */
+ __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
+ xfs_agino_t pagi_freecount; /* number of free inodes */
+ xfs_agino_t pagi_count; /* number of allocated inodes */
+
+ /*
+ * Inode allocation search lookup optimisation.
+ * If the pagino matches, the search for new inodes
+ * doesn't need to search the near ones again straight away
+ */
+ xfs_agino_t pagl_pagino;
+ xfs_agino_t pagl_leftrec;
+ xfs_agino_t pagl_rightrec;
+ int pagb_count; /* pagb slots in use */
+} xfs_perag_t;
#define LIBXFS_MOUNT_ROOTINOS 0x0001
#define LIBXFS_MOUNT_DEBUGGER 0x0002
diff --git a/include/xfs_ag.h b/include/xfs_ag.h
index 317aa86..1cb740a 100644
--- a/include/xfs_ag.h
+++ b/include/xfs_ag.h
@@ -227,59 +227,6 @@ typedef struct xfs_agfl {
} xfs_agfl_t;
/*
- * Per-ag incore structure, copies of information in agf and agi,
- * to improve the performance of allocation group selection.
- */
-#define XFS_PAGB_NUM_SLOTS 128
-
-typedef struct xfs_perag {
- struct xfs_mount *pag_mount; /* owner filesystem */
- xfs_agnumber_t pag_agno; /* AG this structure belongs to */
- atomic_t pag_ref; /* perag reference count */
- char pagf_init; /* this agf's entry is initialized */
- char pagi_init; /* this agi's entry is initialized */
- char pagf_metadata; /* the agf is preferred to be metadata */
- char pagi_inodeok; /* The agi is ok for inodes */
- __uint8_t pagf_levels[XFS_BTNUM_AGF];
- /* # of levels in bno & cnt btree */
- __uint32_t pagf_flcount; /* count of blocks in freelist */
- xfs_extlen_t pagf_freeblks; /* total free blocks */
- xfs_extlen_t pagf_longest; /* longest free space */
- __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
- xfs_agino_t pagi_freecount; /* number of free inodes */
- xfs_agino_t pagi_count; /* number of allocated inodes */
-
- /*
- * Inode allocation search lookup optimisation.
- * If the pagino matches, the search for new inodes
- * doesn't need to search the near ones again straight away
- */
- xfs_agino_t pagl_pagino;
- xfs_agino_t pagl_leftrec;
- xfs_agino_t pagl_rightrec;
-#ifdef __KERNEL__
- spinlock_t pagb_lock; /* lock for pagb_tree */
- struct rb_root pagb_tree; /* ordered tree of busy extents */
-
- atomic_t pagf_fstrms; /* # of filestreams active in this AG */
-
- spinlock_t pag_ici_lock; /* incore inode cache lock */
- struct radix_tree_root pag_ici_root; /* incore inode cache root */
- int pag_ici_reclaimable; /* reclaimable inodes */
- struct mutex pag_ici_reclaim_lock; /* serialisation point */
- unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
-
- /* buffer cache index */
- spinlock_t pag_buf_lock; /* lock for pag_buf_tree */
- struct rb_root pag_buf_tree; /* ordered tree of active buffers */
-
- /* for rcu-safe freeing */
- struct rcu_head rcu_head;
-#endif
- int pagb_count; /* pagb slots in use */
-} xfs_perag_t;
-
-/*
* tags for inode radix tree
*/
#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (39 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 40/49] xfs: make struct xfs_perag kernel only Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 18:23 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation Dave Chinner
` (8 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
Introduce a new structure xfs_trans_res to hold transaction
reservation item info per log ticket.
We also need to improve xfs_trans_resv_calc() by initializing the
log count as well as log flags for permanent log reservation.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 2 +-
include/xfs_trans_resv.h | 125 ++++++++++++++++++++++++++---------------------
libxfs/trans.c | 2 +-
libxfs/xfs_trans_resv.c | 121 ++++++++++++++++++++++++++++++++++-----------
mkfs/maxtrres.c | 17 ++++---
5 files changed, 172 insertions(+), 95 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index 03caf9c..e58fcdc 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -203,7 +203,7 @@ typedef struct xfs_mount {
int m_ialloc_blks; /* blocks in inode allocation */
int m_litino; /* size of inode union area */
int m_inoalign_mask;/* mask sb_inoalignmt if used */
- struct xfs_trans_resv m_reservations; /* precomputed res values */
+ struct xfs_trans_resv m_resv; /* precomputed res values */
__uint64_t m_maxicount; /* maximum inode count */
int m_dalign; /* stripe unit */
int m_swidth; /* stripe width */
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
index cc8260e..0aac1fa 100644
--- a/include/xfs_trans_resv.h
+++ b/include/xfs_trans_resv.h
@@ -23,35 +23,45 @@ struct xfs_mount;
/*
* structure for maintaining pre-calculated transaction reservations.
*/
+struct xfs_trans_res {
+ uint tr_logres; /* log space unit in bytes per log ticket */
+ int tr_logcount; /* number of log operations per log ticket */
+ int tr_logflags; /* log flags, currently only used for indicating
+ * a reservation request is permanent or not */
+};
+
struct xfs_trans_resv {
- uint tr_write; /* extent alloc trans */
- uint tr_itruncate; /* truncate trans */
- uint tr_rename; /* rename trans */
- uint tr_link; /* link trans */
- uint tr_remove; /* unlink trans */
- uint tr_symlink; /* symlink trans */
- uint tr_create; /* create trans */
- uint tr_mkdir; /* mkdir trans */
- uint tr_ifree; /* inode free trans */
- uint tr_ichange; /* inode update trans */
- uint tr_growdata; /* fs data section grow trans */
- uint tr_swrite; /* sync write inode trans */
- uint tr_addafork; /* cvt inode to attributed trans */
- uint tr_writeid; /* write setuid/setgid file */
- uint tr_attrinval; /* attr fork buffer invalidation */
- uint tr_attrsetm; /* set/create an attribute at mount time */
- uint tr_attrsetrt; /* set/create an attribute at runtime */
- uint tr_attrrm; /* remove an attribute */
- uint tr_clearagi; /* clear bad agi unlinked ino bucket */
- uint tr_growrtalloc; /* grow realtime allocations */
- uint tr_growrtzero; /* grow realtime zeroing */
- uint tr_growrtfree; /* grow realtime freeing */
- uint tr_qm_sbchange; /* change quota flags */
- uint tr_qm_setqlim; /* adjust quota limits */
- uint tr_qm_dqalloc; /* allocate quota on disk */
- uint tr_qm_quotaoff; /* turn quota off */
- uint tr_qm_equotaoff;/* end of turn quota off */
- uint tr_sb; /* modify superblock */
+ struct xfs_trans_res tr_write; /* extent alloc trans */
+ struct xfs_trans_res tr_itruncate; /* truncate trans */
+ struct xfs_trans_res tr_rename; /* rename trans */
+ struct xfs_trans_res tr_link; /* link trans */
+ struct xfs_trans_res tr_remove; /* unlink trans */
+ struct xfs_trans_res tr_symlink; /* symlink trans */
+ struct xfs_trans_res tr_create; /* create trans */
+ struct xfs_trans_res tr_mkdir; /* mkdir trans */
+ struct xfs_trans_res tr_ifree; /* inode free trans */
+ struct xfs_trans_res tr_ichange; /* inode update trans */
+ struct xfs_trans_res tr_growdata; /* fs data section grow trans */
+ struct xfs_trans_res tr_swrite; /* sync write inode trans */
+ struct xfs_trans_res tr_addafork; /* add inode attr fork trans */
+ struct xfs_trans_res tr_writeid; /* write setuid/setgid file */
+ struct xfs_trans_res tr_attrinval; /* attr fork buffer
+ * invalidation */
+ struct xfs_trans_res tr_attrsetm; /* set/create an attribute at
+ * mount time */
+ struct xfs_trans_res tr_attrsetrt; /* set/create an attribute at
+ * runtime */
+ struct xfs_trans_res tr_attrrm; /* remove an attribute */
+ struct xfs_trans_res tr_clearagi; /* clear agi unlinked bucket */
+ struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */
+ struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */
+ struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */
+ struct xfs_trans_res tr_qm_sbchange; /* change quota flags */
+ struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */
+ struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */
+ struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */
+ struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */
+ struct xfs_trans_res tr_sb; /* modify superblock */
};
/*
@@ -79,39 +89,40 @@ struct xfs_trans_resv {
XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
-#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
-#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
-#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
-#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
-#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
-#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
-#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
-#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
-#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
-#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
-#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
-#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
-#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
-#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
-#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
+#define XFS_WRITE_LOG_RES(mp) ((mp)->m_resv.tr_write.tr_logres)
+#define XFS_RENAME_LOG_RES(mp) ((mp)->m_resv.tr_rename.tr_logres)
+#define XFS_LINK_LOG_RES(mp) ((mp)->m_resv.tr_link.tr_logres)
+#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_resv.tr_remove.tr_logres)
+#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_resv.tr_symlink.tr_logres)
+#define XFS_CREATE_LOG_RES(mp) ((mp)->m_resv.tr_create.tr_logres)
+#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_resv.tr_mkdir.tr_logres)
+#define XFS_IFREE_LOG_RES(mp) ((mp)->m_resv.tr_ifree.tr_logres)
+#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
+#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_resv.tr_ichange.tr_logres)
+#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_resv.tr_growdata.tr_logres)
+#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_resv.tr_itruncate.tr_logres)
+#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_resv.tr_growrtzero.tr_logres)
+#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_resv.tr_growrtfree.tr_logres)
+#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_resv.tr_growrtalloc.tr_logres)
+
/*
* Logging the inode timestamps on an fsync -- same as SWRITE
* as long as SWRITE logs the entire inode core
*/
-#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
-#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
-#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
-#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm)
-#define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt)
-#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
-#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
-#define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange)
-#define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim)
-#define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc)
-#define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff)
-#define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff)
-#define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb)
+#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
+#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
+#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_resv.tr_addafork.tr_logres)
+#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_resv.tr_attrsetm.tr_logres)
+#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_resv.tr_attrinval.tr_logres)
+#define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_resv.tr_attrsetrt.tr_logres)
+#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_resv.tr_attrrm.tr_logres)
+#define XFS_SB_LOG_RES(mp) ((mp)->m_resv.tr_sb.tr_logres)
+#define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_resv.tr_qm_setqlim.tr_logres)
+#define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_resv.tr_qm_dqalloc.tr_logres)
+#define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_resv.tr_qm_sbchange.tr_logres)
+#define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_resv.tr_qm_quotaoff.tr_logres)
+#define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_resv.tr_qm_equotaoff.tr_logres)
+#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_resv.tr_clearagi.tr_logres)
/*
* Various log count values.
diff --git a/libxfs/trans.c b/libxfs/trans.c
index d0a91b1..2fc0ecc 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -33,7 +33,7 @@ void
libxfs_trans_init(
struct xfs_mount *mp)
{
- xfs_trans_resv_calc(mp, &mp->m_reservations);
+ xfs_trans_resv_calc(mp, &mp->m_resv);
}
/*
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index 7a391e3..e0b8ef6 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -646,32 +646,97 @@ xfs_trans_resv_calc(
struct xfs_mount *mp,
struct xfs_trans_resv *resp)
{
- resp->tr_write = xfs_calc_write_reservation(mp);
- resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
- resp->tr_rename = xfs_calc_rename_reservation(mp);
- resp->tr_link = xfs_calc_link_reservation(mp);
- resp->tr_remove = xfs_calc_remove_reservation(mp);
- resp->tr_symlink = xfs_calc_symlink_reservation(mp);
- resp->tr_create = xfs_calc_create_reservation(mp);
- resp->tr_mkdir = xfs_calc_mkdir_reservation(mp);
- resp->tr_ifree = xfs_calc_ifree_reservation(mp);
- resp->tr_ichange = xfs_calc_ichange_reservation(mp);
- resp->tr_growdata = xfs_calc_growdata_reservation(mp);
- resp->tr_swrite = xfs_calc_swrite_reservation(mp);
- resp->tr_writeid = xfs_calc_writeid_reservation(mp);
- resp->tr_addafork = xfs_calc_addafork_reservation(mp);
- resp->tr_attrinval = xfs_calc_attrinval_reservation(mp);
- resp->tr_attrsetm = xfs_calc_attrsetm_reservation(mp);
- resp->tr_attrsetrt = xfs_calc_attrsetrt_reservation(mp);
- resp->tr_attrrm = xfs_calc_attrrm_reservation(mp);
- resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp);
- resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp);
- resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp);
- resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp);
- resp->tr_qm_sbchange = xfs_calc_qm_sbchange_reservation(mp);
- resp->tr_qm_setqlim = xfs_calc_qm_setqlim_reservation(mp);
- resp->tr_qm_dqalloc = xfs_calc_qm_dqalloc_reservation(mp);
- resp->tr_qm_quotaoff = xfs_calc_qm_quotaoff_reservation(mp);
- resp->tr_qm_equotaoff = xfs_calc_qm_quotaoff_end_reservation(mp);
- resp->tr_sb = xfs_calc_sb_reservation(mp);
+ /*
+ * The following transactions are logged in physical format and
+ * require a permanent reservation on space.
+ */
+ resp->tr_write.tr_logres = xfs_calc_write_reservation(mp);
+ resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT;
+ resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp);
+ resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT;
+ resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp);
+ resp->tr_rename.tr_logcount = XFS_RENAME_LOG_COUNT;
+ resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_link.tr_logres = xfs_calc_link_reservation(mp);
+ resp->tr_link.tr_logcount = XFS_LINK_LOG_COUNT;
+ resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp);
+ resp->tr_remove.tr_logcount = XFS_REMOVE_LOG_COUNT;
+ resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp);
+ resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT;
+ resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_create.tr_logres = xfs_calc_create_reservation(mp);
+ resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT;
+ resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp);
+ resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT;
+ resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp);
+ resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT;
+ resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_addafork.tr_logres = xfs_calc_addafork_reservation(mp);
+ resp->tr_addafork.tr_logcount = XFS_ADDAFORK_LOG_COUNT;
+ resp->tr_addafork.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_attrinval.tr_logres = xfs_calc_attrinval_reservation(mp);
+ resp->tr_attrinval.tr_logcount = XFS_ATTRINVAL_LOG_COUNT;
+ resp->tr_attrinval.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_attrsetm.tr_logres = xfs_calc_attrsetm_reservation(mp);
+ resp->tr_attrsetm.tr_logcount = XFS_ATTRSET_LOG_COUNT;
+ resp->tr_attrsetm.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_attrrm.tr_logres = xfs_calc_attrrm_reservation(mp);
+ resp->tr_attrrm.tr_logcount = XFS_ATTRRM_LOG_COUNT;
+ resp->tr_attrrm.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_growrtalloc.tr_logres = xfs_calc_growrtalloc_reservation(mp);
+ resp->tr_growrtalloc.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
+ resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp);
+ resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT;
+ resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+ /*
+ * The following transactions are logged in logical format with
+ * a default log count.
+ */
+ resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp);
+ resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT;
+
+ resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp);
+ resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT;
+
+ resp->tr_qm_quotaoff.tr_logres = xfs_calc_qm_quotaoff_reservation(mp);
+ resp->tr_qm_quotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT;
+
+ resp->tr_qm_equotaoff.tr_logres =
+ xfs_calc_qm_quotaoff_end_reservation(mp);
+ resp->tr_qm_equotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT;
+
+ resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp);
+ resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT;
+
+ /* The following transaction are logged in logical format */
+ resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp);
+ resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
+ resp->tr_swrite.tr_logres = xfs_calc_swrite_reservation(mp);
+ resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp);
+ resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp);
+ resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp);
+ resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp);
+ resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp);
}
diff --git a/mkfs/maxtrres.c b/mkfs/maxtrres.c
index 7da83aa..b2d2a5a 100644
--- a/mkfs/maxtrres.c
+++ b/mkfs/maxtrres.c
@@ -47,22 +47,23 @@ max_attrsetm_trans_res_adjust(
nblks += XFS_B_TO_FSB(mp, size);
nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK);
res = XFS_ATTRSETM_LOG_RES(mp) + XFS_ATTRSETRT_LOG_RES(mp) * nblks;
- mp->m_reservations.tr_attrsetm = res;
+ mp->m_resv.tr_attrsetm.tr_logres = res;
}
static int
max_trans_res_by_mount(
struct xfs_mount *mp)
{
- uint *p;
- int rval;
- struct xfs_trans_resv *tr = &mp->m_reservations;
+ struct xfs_trans_resv *tr = &mp->m_resv;
+ struct xfs_trans_res *p;
+ struct xfs_trans_res rval = {0};
- for (rval = 0, p = (uint *)tr; p < (uint *)(tr + 1); p++) {
- if ((int)*p > rval)
- rval = (int)*p;
+ for (p = (struct xfs_trans_res *)tr;
+ p < (struct xfs_trans_res *)(tr + 1); p++) {
+ if (p->tr_logres > rval.tr_logres)
+ rval = *p;
}
- return rval;
+ return rval.tr_logres;
}
int
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (40 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 18:33 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 43/49] xfs: Make writeid transaction use tr_writeid Dave Chinner
` (7 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
A preparation step.
For now fsync_ts transaction use the pre-calculated log reservation
size of tr_swrite.
This patch introduce a new item tr_fsyncts to mp->m_reservations
structure so that we can fetch the log reservation value for it
in a same manner to others.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
---
include/xfs_trans_resv.h | 3 ++-
libxfs/xfs_trans_resv.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
index 0aac1fa..326f17d 100644
--- a/include/xfs_trans_resv.h
+++ b/include/xfs_trans_resv.h
@@ -62,6 +62,7 @@ struct xfs_trans_resv {
struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */
struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */
struct xfs_trans_res tr_sb; /* modify superblock */
+ struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */
};
/*
@@ -109,7 +110,7 @@ struct xfs_trans_resv {
* Logging the inode timestamps on an fsync -- same as SWRITE
* as long as SWRITE logs the entire inode core
*/
-#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
+#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_resv.tr_fsyncts.tr_logres)
#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_resv.tr_addafork.tr_logres)
#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_resv.tr_attrsetm.tr_logres)
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index e0b8ef6..36aeafe 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -734,6 +734,7 @@ xfs_trans_resv_calc(
resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp);
resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
resp->tr_swrite.tr_logres = xfs_calc_swrite_reservation(mp);
+ resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp);
resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp);
resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp);
resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp);
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 43/49] xfs: Make writeid transaction use tr_writeid
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (41 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 18:38 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface Dave Chinner
` (6 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
tr_writeid is defined at mp->m_resv structure, however, it does not
really being used when it should be..
This patch changes it to tr_writeid to fetch the correct log
reservation size.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_trans_resv.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
index 326f17d..b8d5666 100644
--- a/include/xfs_trans_resv.h
+++ b/include/xfs_trans_resv.h
@@ -111,7 +111,7 @@ struct xfs_trans_resv {
* as long as SWRITE logs the entire inode core
*/
#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_resv.tr_fsyncts.tr_logres)
-#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
+#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_resv.tr_writeid.tr_logres)
#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_resv.tr_addafork.tr_logres)
#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_resv.tr_attrsetm.tr_logres)
#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_resv.tr_attrinval.tr_logres)
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (42 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 43/49] xfs: Make writeid transaction use tr_writeid Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 19:12 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro Dave Chinner
` (5 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
With the new xfs_trans_res structure has been introduced, the log
reservation size, log count as well as log flags are pre-initialized
at mount time. So it's time to refine xfs_trans_reserve() interface
to be more neat.
Also, introduce a new helper M_RES() to return a pointer to the
mp->m_resv structure to simplify the input.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/libxfs.h | 3 +-
include/xfs_trans_resv.h | 3 ++
libxfs/trans.c | 20 +++++------
libxfs/util.c | 15 +++++---
libxfs/xfs_attr.c | 33 +++++++++---------
libxfs/xfs_bmap.c | 4 +--
libxfs/xfs_trans_resv.c | 7 ++--
mkfs/proto.c | 24 ++++++++-----
mkfs/xfs_mkfs.c | 5 ++-
repair/phase5.c | 3 +-
repair/phase6.c | 89 +++++++++++++++++++++++-------------------------
repair/phase7.c | 7 ++--
12 files changed, 115 insertions(+), 98 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index e58fcdc..0b70f5c 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -512,7 +512,8 @@ typedef struct xfs_trans {
extern xfs_trans_t *libxfs_trans_alloc (xfs_mount_t *, int);
extern xfs_trans_t *libxfs_trans_dup (xfs_trans_t *);
-extern int libxfs_trans_reserve (xfs_trans_t *, uint,uint,uint,uint,uint);
+extern int libxfs_trans_reserve(struct xfs_trans *, struct xfs_trans_res *,
+ uint, uint);
extern int libxfs_trans_commit (xfs_trans_t *, uint);
extern void libxfs_trans_cancel (xfs_trans_t *, int);
extern xfs_buf_t *libxfs_trans_getsb (xfs_trans_t *, xfs_mount_t *, int);
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
index b8d5666..140d3f3 100644
--- a/include/xfs_trans_resv.h
+++ b/include/xfs_trans_resv.h
@@ -65,6 +65,9 @@ struct xfs_trans_resv {
struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */
};
+/* shorthand way of accessing reservation structure */
+#define M_RES(mp) (&(mp)->m_resv)
+
/*
* Per-extent log reservation for the allocation btree changes
* involved in freeing or allocating an extent.
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 2fc0ecc..6a05673 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -91,7 +91,7 @@ libxfs_trans_roll(
struct xfs_inode *dp)
{
struct xfs_trans *trans;
- unsigned int logres, count;
+ struct xfs_trans_res tres;
int error;
/*
@@ -103,8 +103,8 @@ libxfs_trans_roll(
/*
* Copy the critical parameters from one trans to the next.
*/
- logres = trans->t_log_res;
- count = trans->t_log_count;
+ tres.tr_logres = trans->t_log_res;
+ tres.tr_logcount = trans->t_log_count;
*tpp = xfs_trans_dup(trans);
/*
@@ -128,8 +128,8 @@ libxfs_trans_roll(
* across this call, or that anything that is locked be logged in
* the prior and the next transactions.
*/
- error = xfs_trans_reserve(trans, 0, logres, 0,
- XFS_TRANS_PERM_LOG_RES, count);
+ tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+ error = xfs_trans_reserve(trans, &tres, 0, 0);
/*
* Ensure that the inode is in the new transaction and locked.
*/
@@ -176,12 +176,10 @@ libxfs_trans_dup(
int
libxfs_trans_reserve(
- xfs_trans_t *tp,
- uint blocks,
- uint logspace,
- uint rtextents,
- uint flags,
- uint logcount)
+ struct xfs_trans *tp,
+ struct xfs_trans_res *resp,
+ uint blocks,
+ uint rtextents)
{
xfs_sb_t *mpsb = &tp->t_mountp->m_sb;
diff --git a/libxfs/util.c b/libxfs/util.c
index 1d3113a..d7459e0 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -473,7 +473,8 @@ libxfs_alloc_file_space(
tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
resblks = (uint)XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
- error = xfs_trans_reserve(tp, resblks, 0, 0, 0, 0);
+ error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
+ resblks, 0);
if (error)
break;
xfs_trans_ijoin(tp, ip, 0);
@@ -536,7 +537,6 @@ libxfs_inode_alloc(
struct fsxattr *fsx,
xfs_inode_t **ipp)
{
- int i;
xfs_buf_t *ialloc_context;
xfs_inode_t *ip;
xfs_trans_t *ntp;
@@ -555,13 +555,20 @@ libxfs_inode_alloc(
}
if (ialloc_context) {
+ struct xfs_trans_res tres;
+
xfs_trans_bhold(*tp, ialloc_context);
+ tres.tr_logres = (*tp)->t_log_res;
+ tres.tr_logcount = (*tp)->t_log_count;
+
ntp = xfs_trans_dup(*tp);
xfs_trans_commit(*tp, 0);
*tp = ntp;
- if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) {
+ tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+ error = xfs_trans_reserve(*tp, &tres, 0, 0);
+ if (error) {
fprintf(stderr, _("%s: cannot reserve space: %s\n"),
- progname, strerror(i));
+ progname, strerror(error));
exit(1);
}
xfs_trans_bjoin(*tp, ialloc_context);
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 8fe892e..f554e60 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -202,13 +202,14 @@ xfs_attr_set_int(
int valuelen,
int flags)
{
- xfs_da_args_t args;
- xfs_fsblock_t firstblock;
- xfs_bmap_free_t flist;
- int error, err2, committed;
- xfs_mount_t *mp = dp->i_mount;
- int rsvd = (flags & ATTR_ROOT) != 0;
- int local;
+ xfs_da_args_t args;
+ xfs_fsblock_t firstblock;
+ xfs_bmap_free_t flist;
+ int error, err2, committed;
+ struct xfs_mount *mp = dp->i_mount;
+ struct xfs_trans_res tres;
+ int rsvd = (flags & ATTR_ROOT) != 0;
+ int local;
/*
* Attach the dquots to the inode.
@@ -268,11 +269,11 @@ xfs_attr_set_int(
if (rsvd)
args.trans->t_flags |= XFS_TRANS_RESERVE;
- error = xfs_trans_reserve(args.trans, args.total,
- XFS_ATTRSETM_LOG_RES(mp) +
- XFS_ATTRSETRT_LOG_RES(mp) * args.total,
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ATTRSET_LOG_COUNT);
+ tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
+ M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
+ tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
+ tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+ error = xfs_trans_reserve(args.trans, &tres, args.total, 0);
if (error) {
xfs_trans_cancel(args.trans, 0);
return(error);
@@ -492,11 +493,9 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
if (flags & ATTR_ROOT)
args.trans->t_flags |= XFS_TRANS_RESERVE;
- if ((error = xfs_trans_reserve(args.trans,
- XFS_ATTRRM_SPACE_RES(mp),
- XFS_ATTRRM_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_ATTRRM_LOG_COUNT))) {
+ error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm,
+ XFS_ATTRRM_SPACE_RES(mp), 0);
+ if (error) {
xfs_trans_cancel(args.trans, 0);
return(error);
}
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index eeaea94..2d480cc 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -1113,8 +1113,8 @@ xfs_bmap_add_attrfork(
blks = XFS_ADDAFORK_SPACE_RES(mp);
if (rsvd)
tp->t_flags |= XFS_TRANS_RESERVE;
- if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
+ error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0);
+ if (error)
goto error0;
xfs_ilock(ip, XFS_ILOCK_EXCL);
error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index 36aeafe..d134136 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -522,7 +522,8 @@ xfs_calc_attrsetm_reservation(
* Since the runtime attribute transaction space is dependent on the total
* blocks needed for the 1st bmap, here we calculate out the space unit for
* one block so that the caller could figure out the total space according
- * to the attibute extent length in blocks by: ext * XFS_ATTRSETRT_LOG_RES(mp).
+ * to the attibute extent length in blocks by:
+ * ext * M_RES(mp)->tr_attrsetrt.tr_logres
*/
STATIC uint
xfs_calc_attrsetrt_reservation(
@@ -594,14 +595,14 @@ xfs_calc_qm_setqlim_reservation(
/*
* Allocating quota on disk if needed.
- * the write transaction log space: XFS_WRITE_LOG_RES(mp)
+ * the write transaction log space: M_RES(mp)->tr_write.tr_logres
* the unit of quota allocation: one system block size
*/
STATIC uint
xfs_calc_qm_dqalloc_reservation(
struct xfs_mount *mp)
{
- return XFS_WRITE_LOG_RES(mp) +
+ return M_RES(mp)->tr_write.tr_logres +
xfs_calc_buf_res(1,
XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
}
diff --git a/mkfs/proto.c b/mkfs/proto.c
index ee84699..e33d238 100644
--- a/mkfs/proto.c
+++ b/mkfs/proto.c
@@ -119,7 +119,9 @@ getres(
mp = tp->t_mountp;
for (i = 0, r = MKFS_BLOCKRES(blocks); r >= blocks; r--) {
- i = libxfs_trans_reserve(tp, r, 0, 0, 0, 0);
+ struct xfs_trans_res tres = {0};
+
+ i = libxfs_trans_reserve(tp, &tres, r, 0);
if (i == 0)
return;
}
@@ -615,13 +617,16 @@ rtinit(
xfs_trans_t *tp;
struct cred creds;
struct fsxattr fsxattrs;
+ struct xfs_trans_res tres = {0};
/*
* First, allocate the inodes.
*/
tp = libxfs_trans_alloc(mp, 0);
- if ((i = libxfs_trans_reserve(tp, MKFS_BLOCKRES_INODE, 0, 0, 0, 0)))
+ i = libxfs_trans_reserve(tp, &tres, MKFS_BLOCKRES_INODE, 0);
+ if (i)
res_failed(i);
+
memset(&creds, 0, sizeof(creds));
memset(&fsxattrs, 0, sizeof(fsxattrs));
error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
@@ -658,9 +663,11 @@ rtinit(
* Next, give the bitmap file some zero-filled blocks.
*/
tp = libxfs_trans_alloc(mp, 0);
- if ((i = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks +
- (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0)))
+ i = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks +
+ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+ if (i)
res_failed(i);
+
libxfs_trans_ijoin(tp, rbmip, 0);
libxfs_trans_ihold(tp, rbmip);
bno = 0;
@@ -694,9 +701,9 @@ rtinit(
*/
tp = libxfs_trans_alloc(mp, 0);
nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
- if ((i = libxfs_trans_reserve(tp,
- nsumblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1),
- 0, 0, 0, 0)))
+ i = libxfs_trans_reserve(tp, &tres, nsumblocks +
+ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+ if (i)
res_failed(i);
libxfs_trans_ijoin(tp, rsumip, 0);
libxfs_trans_ihold(tp, rsumip);
@@ -731,7 +738,8 @@ rtinit(
*/
for (bno = 0; bno < mp->m_sb.sb_rextents; bno = ebno) {
tp = libxfs_trans_alloc(mp, 0);
- if ((i = libxfs_trans_reserve(tp, 0, 0, 0, 0, 0)))
+ i = libxfs_trans_reserve(tp, &tres, 0, 0);
+ if (i)
res_failed(i);
libxfs_trans_ijoin(tp, rbmip, 0);
libxfs_trans_ihold(tp, rbmip);
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index bb5d8d4..a940150 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2821,6 +2821,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
for (agno = 0; agno < agcount; agno++) {
xfs_alloc_arg_t args;
xfs_trans_t *tp;
+ struct xfs_trans_res tres = {0};
memset(&args, 0, sizeof(args));
args.tp = tp = libxfs_trans_alloc(mp, 0);
@@ -2828,8 +2829,10 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
args.agno = agno;
args.alignment = 1;
args.pag = xfs_perag_get(mp,agno);
- if ((c = libxfs_trans_reserve(tp, worst_freelist, 0, 0, 0, 0)))
+ c = libxfs_trans_reserve(tp, &tres, worst_freelist, 0);
+ if (c)
res_failed(c);
+
libxfs_alloc_fix_freelist(&args, 0);
xfs_perag_put(args.pag);
libxfs_trans_commit(tp, 0);
diff --git a/repair/phase5.c b/repair/phase5.c
index 2eae42a..27bb47e 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -1405,6 +1405,7 @@ build_agf_agfl(xfs_mount_t *mp,
{
xfs_alloc_arg_t args;
xfs_trans_t *tp;
+ struct xfs_trans_res tres = {0};
memset(&args, 0, sizeof(args));
args.tp = tp = libxfs_trans_alloc(mp, 0);
@@ -1412,7 +1413,7 @@ build_agf_agfl(xfs_mount_t *mp,
args.agno = agno;
args.alignment = 1;
args.pag = xfs_perag_get(mp,agno);
- libxfs_trans_reserve(tp, XFS_MIN_FREELIST(agf, mp), 0, 0, 0, 0);
+ libxfs_trans_reserve(tp, &tres, XFS_MIN_FREELIST(agf, mp), 0);
libxfs_alloc_fix_freelist(&args, 0);
xfs_perag_put(args.pag);
libxfs_trans_commit(tp, 0);
diff --git a/repair/phase6.c b/repair/phase6.c
index 2905a1c..df9b92e 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -429,13 +429,15 @@ mk_rbmino(xfs_mount_t *mp)
xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
int vers;
int times;
+ struct xfs_trans_res tres = {0};
/*
* first set up inode
*/
tp = libxfs_trans_alloc(mp, 0);
- if ((i = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0)))
+ i = libxfs_trans_reserve(tp, &tres, 10, 0);
+ if (i)
res_failed(i);
error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip);
@@ -490,8 +492,9 @@ mk_rbmino(xfs_mount_t *mp)
* from mkfs)
*/
tp = libxfs_trans_alloc(mp, 0);
- if ((error = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks +
- (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0)))
+ error = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks +
+ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+ if (error)
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
@@ -536,13 +539,15 @@ fill_rbmino(xfs_mount_t *mp)
int error;
xfs_dfiloff_t bno;
xfs_bmbt_irec_t map;
+ struct xfs_trans_res tres = {0};
bmp = btmcompute;
bno = 0;
tp = libxfs_trans_alloc(mp, 0);
- if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0)))
+ error = libxfs_trans_reserve(tp, &tres, 10, 0);
+ if (error)
res_failed(error);
error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip);
@@ -604,6 +609,7 @@ fill_rsumino(xfs_mount_t *mp)
xfs_dfiloff_t bno;
xfs_dfiloff_t end_bno;
xfs_bmbt_irec_t map;
+ struct xfs_trans_res tres = {0};
smp = sumcompute;
bno = 0;
@@ -611,7 +617,8 @@ fill_rsumino(xfs_mount_t *mp)
tp = libxfs_trans_alloc(mp, 0);
- if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0)))
+ error = libxfs_trans_reserve(tp, &tres, 10, 0);
+ if (error)
res_failed(error);
error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip);
@@ -677,14 +684,15 @@ mk_rsumino(xfs_mount_t *mp)
xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
int vers;
int times;
+ struct xfs_trans_res tres = {0};
/*
* first set up inode
*/
tp = libxfs_trans_alloc(mp, 0);
- if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT)))
+ i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0);
+ if (i)
res_failed(i);
error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip);
@@ -742,11 +750,12 @@ mk_rsumino(xfs_mount_t *mp)
xfs_bmap_init(&flist, &first);
nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
- if ((error = libxfs_trans_reserve(tp,
- mp->m_sb.sb_rbmblocks +
- (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1),
- BBTOB(128), 0, XFS_TRANS_PERM_LOG_RES,
- XFS_DEFAULT_PERM_LOG_COUNT)))
+ tres.tr_logres = BBTOB(128);
+ tres.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
+ tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+ error = libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks +
+ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+ if (error)
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
@@ -798,8 +807,8 @@ mk_root_dir(xfs_mount_t *mp)
tp = libxfs_trans_alloc(mp, 0);
ip = NULL;
- if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT)))
+ i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0);
+ if (i)
res_failed(i);
error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rootino, 0, 0, &ip);
@@ -904,8 +913,8 @@ mk_orphanage(xfs_mount_t *mp)
xfs_bmap_init(&flist, &first);
nres = XFS_MKDIR_SPACE_RES(mp, xname.len);
- if ((i = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT)))
+ i = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0);
+ if (i)
res_failed(i);
/*
@@ -1041,10 +1050,9 @@ mv_orphanage(
if (err) {
ASSERT(err == ENOENT);
- if ((err = libxfs_trans_reserve(tp, nres,
- XFS_RENAME_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_RENAME_LOG_COUNT)))
+ err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename,
+ nres, 0);
+ if (err)
do_error(
_("space reservation failed (%d), filesystem may be out of space\n"),
err);
@@ -1085,10 +1093,9 @@ mv_orphanage(
libxfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC);
} else {
- if ((err = libxfs_trans_reserve(tp, nres,
- XFS_RENAME_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_RENAME_LOG_COUNT)))
+ err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename,
+ nres, 0);
+ if (err)
do_error(
_("space reservation failed (%d), filesystem may be out of space\n"),
err);
@@ -1143,8 +1150,8 @@ mv_orphanage(
* also accounted for in the create
*/
nres = XFS_DIRENTER_SPACE_RES(mp, xname.len);
- err = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
+ err = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove,
+ nres, 0);
if (err)
do_error(
_("space reservation failed (%d), filesystem may be out of space\n"),
@@ -1239,8 +1246,7 @@ longform_dir2_rebuild(
tp = libxfs_trans_alloc(mp, 0);
nres = XFS_REMOVE_SPACE_RES(mp);
- error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
if (error)
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
@@ -1280,8 +1286,8 @@ longform_dir2_rebuild(
tp = libxfs_trans_alloc(mp, 0);
nres = XFS_CREATE_SPACE_RES(mp, p->name.len);
- error = libxfs_trans_reserve(tp, nres, XFS_CREATE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_create,
+ nres, 0);
if (error) {
do_warn(
_("space reservation failed (%d), filesystem may be out of space\n"),
@@ -1342,8 +1348,7 @@ dir2_kill_block(
tp = libxfs_trans_alloc(mp, 0);
nres = XFS_REMOVE_SPACE_RES(mp);
- error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
if (error)
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
@@ -1531,8 +1536,7 @@ longform_dir2_entry_check_data(
freetab->nents = db + 1;
tp = libxfs_trans_alloc(mp, 0);
- error = libxfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, 0, 0);
if (error)
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
@@ -2589,10 +2593,8 @@ process_dir_inode(
* new define in ourselves.
*/
nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp);
- error = libxfs_trans_reserve(tp, nres,
- XFS_REMOVE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_REMOVE_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove,
+ nres, 0);
if (error)
res_failed(error);
@@ -2640,8 +2642,7 @@ process_dir_inode(
ASSERT(tp != NULL);
nres = XFS_MKDIR_SPACE_RES(mp, 2);
- error = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT);
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0);
if (error)
res_failed(error);
@@ -2702,12 +2703,8 @@ process_dir_inode(
ASSERT(tp != NULL);
nres = XFS_MKDIR_SPACE_RES(mp, 1);
- error = libxfs_trans_reserve(tp, nres,
- XFS_MKDIR_LOG_RES(mp),
- 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_MKDIR_LOG_COUNT);
-
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir,
+ nres, 0);
if (error)
res_failed(error);
diff --git a/repair/phase7.c b/repair/phase7.c
index bd1668e..18f2d88 100644
--- a/repair/phase7.c
+++ b/repair/phase7.c
@@ -68,13 +68,12 @@ update_inode_nlinks(
xfs_inode_t *ip;
int error;
int dirty;
+ int nres;
tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE);
- error = libxfs_trans_reserve(tp, (no_modify ? 0 : 10),
- XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES,
- XFS_REMOVE_LOG_COUNT);
-
+ nres = no_modify ? 0 : 10;
+ error = libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
ASSERT(error == 0);
error = libxfs_trans_iget(mp, tp, ino, 0, 0, &ip);
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (43 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 19:23 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 46/49] xfs: Add xfs_log_rlimit.c Dave Chinner
` (4 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
Get rid of all XFS_XXX_LOG_RES() macros since they are obsoleted now.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_trans_resv.h | 36 ------------------------------------
mkfs/maxtrres.c | 5 +++--
2 files changed, 3 insertions(+), 38 deletions(-)
diff --git a/include/xfs_trans_resv.h b/include/xfs_trans_resv.h
index 140d3f3..de7de9a 100644
--- a/include/xfs_trans_resv.h
+++ b/include/xfs_trans_resv.h
@@ -92,42 +92,6 @@ struct xfs_trans_resv {
(XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
-
-#define XFS_WRITE_LOG_RES(mp) ((mp)->m_resv.tr_write.tr_logres)
-#define XFS_RENAME_LOG_RES(mp) ((mp)->m_resv.tr_rename.tr_logres)
-#define XFS_LINK_LOG_RES(mp) ((mp)->m_resv.tr_link.tr_logres)
-#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_resv.tr_remove.tr_logres)
-#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_resv.tr_symlink.tr_logres)
-#define XFS_CREATE_LOG_RES(mp) ((mp)->m_resv.tr_create.tr_logres)
-#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_resv.tr_mkdir.tr_logres)
-#define XFS_IFREE_LOG_RES(mp) ((mp)->m_resv.tr_ifree.tr_logres)
-#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_resv.tr_swrite.tr_logres)
-#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_resv.tr_ichange.tr_logres)
-#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_resv.tr_growdata.tr_logres)
-#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_resv.tr_itruncate.tr_logres)
-#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_resv.tr_growrtzero.tr_logres)
-#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_resv.tr_growrtfree.tr_logres)
-#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_resv.tr_growrtalloc.tr_logres)
-
-/*
- * Logging the inode timestamps on an fsync -- same as SWRITE
- * as long as SWRITE logs the entire inode core
- */
-#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_resv.tr_fsyncts.tr_logres)
-#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_resv.tr_writeid.tr_logres)
-#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_resv.tr_addafork.tr_logres)
-#define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_resv.tr_attrsetm.tr_logres)
-#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_resv.tr_attrinval.tr_logres)
-#define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_resv.tr_attrsetrt.tr_logres)
-#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_resv.tr_attrrm.tr_logres)
-#define XFS_SB_LOG_RES(mp) ((mp)->m_resv.tr_sb.tr_logres)
-#define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_resv.tr_qm_setqlim.tr_logres)
-#define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_resv.tr_qm_dqalloc.tr_logres)
-#define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_resv.tr_qm_sbchange.tr_logres)
-#define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_resv.tr_qm_quotaoff.tr_logres)
-#define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_resv.tr_qm_equotaoff.tr_logres)
-#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_resv.tr_clearagi.tr_logres)
-
/*
* Various log count values.
*/
diff --git a/mkfs/maxtrres.c b/mkfs/maxtrres.c
index b2d2a5a..59cdcfd 100644
--- a/mkfs/maxtrres.c
+++ b/mkfs/maxtrres.c
@@ -46,8 +46,9 @@ max_attrsetm_trans_res_adjust(
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
nblks += XFS_B_TO_FSB(mp, size);
nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK);
- res = XFS_ATTRSETM_LOG_RES(mp) + XFS_ATTRSETRT_LOG_RES(mp) * nblks;
- mp->m_resv.tr_attrsetm.tr_logres = res;
+ res = M_RES(mp)->tr_attrsetm.tr_logres +
+ M_RES(mp)->tr_attrsetrt.tr_logres * nblks;
+ M_RES(mp)->tr_attrsetm.tr_logres = res;
}
static int
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 46/49] xfs: Add xfs_log_rlimit.c
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (44 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 20:31 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 47/49] xfs: Add read-only support for dirent filetype field Dave Chinner
` (3 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Jie Liu <jeff.liu@oracle.com>
Add source files for xfs_log_rlimit.c The new file is used for log
size calculations and validation shared with userspace.
[dchinner: xfs_log_calc_max_attrsetm_res() does not modify the
tr_attrsetm reservation, just calculates the maximum. ]
[dchinner: rework loop in xfs_log_get_max_trans_res() ]
[dchinner: implement xfs_log_calc_unit_res() in util.c to give mkfs
a worse case calculation of the log size needed. ]
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_log_format.h | 11 +++-
libxfs/Makefile | 15 ++++--
libxfs/util.c | 107 +++++++++++++++++++++++++++++++++++++
libxfs/xfs_log_rlimit.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++
mkfs/maxtrres.c | 60 +++++----------------
mkfs/xfs_mkfs.c | 95 +++++++++++++++++----------------
mkfs/xfs_mkfs.h | 4 +-
7 files changed, 328 insertions(+), 99 deletions(-)
create mode 100644 libxfs/xfs_log_rlimit.c
diff --git a/include/xfs_log_format.h b/include/xfs_log_format.h
index bcd1c34..a9429a4 100644
--- a/include/xfs_log_format.h
+++ b/include/xfs_log_format.h
@@ -18,6 +18,9 @@
#ifndef __XFS_LOG_FORMAT_H__
#define __XFS_LOG_FORMAT_H__
+struct xfs_mount;
+struct xfs_trans_res;
+
/*
* On-disk Log Format definitions.
*
@@ -49,6 +52,9 @@ typedef __uint32_t xlog_tid_t;
#define XLOG_HEADER_SIZE 512
+/* Minimum number of transactions that must fit in the log (defined by mkfs) */
+#define XFS_MIN_LOG_FACTOR 3
+
#define XLOG_REC_SHIFT(log) \
BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
@@ -133,7 +139,6 @@ typedef struct xlog_op_header {
__u16 oh_res2; /* 32 bit align : 2 b */
} xlog_op_header_t;
-
/* valid values for h_fmt */
#define XLOG_FMT_UNKNOWN 0
#define XLOG_FMT_LINUX_LE 1
@@ -761,4 +766,8 @@ struct xfs_icreate_log {
__be32 icl_gen; /* inode generation number to use */
};
+int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
+int xfs_log_calc_minimum_size(struct xfs_mount *);
+
+
#endif /* __XFS_LOG_FORMAT_H__ */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 5608020..f0cbae3 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -17,14 +17,23 @@ CFILES = cache.c \
xfs_alloc.c \
xfs_alloc_btree.c \
xfs_attr.c \
+ xfs_attr_leaf.c \
xfs_attr_remote.c \
+ xfs_bmap.c \
+ xfs_bmap_btree.c \
xfs_btree.c \
+ xfs_da_btree.c \
+ xfs_dir2.c \
+ xfs_dir2_block.c \
+ xfs_dir2_data.c \
+ xfs_dir2_leaf.c \
+ xfs_dir2_node.c \
+ xfs_dir2_sf.c \
xfs_ialloc.c \
xfs_inode_buf.c \
xfs_inode_fork.c \
- xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \
- xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \
- xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \
+ xfs_ialloc_btree.c \
+ xfs_log_rlimit.c \
xfs_rtalloc.c \
xfs_sb.c \
xfs_symlink_remote.c \
diff --git a/libxfs/util.c b/libxfs/util.c
index d7459e0..460fcb3 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -22,6 +22,113 @@
#include <stdarg.h>
/*
+ * Calculate the worst case log unit reservation for a given superblock
+ * configuration. Copied and munged from the kernel code, and assumes a
+ * worse case header usage (maximum log buffer sizes)
+ */
+int
+xfs_log_calc_unit_res(
+ struct xfs_mount *mp,
+ int unit_bytes)
+{
+ int iclog_space;
+ int iclog_header_size;
+ int iclog_size;
+ uint num_headers;
+
+ if (xfs_sb_version_haslogv2(&mp->m_sb)) {
+ iclog_size = XLOG_MAX_RECORD_BSIZE;
+ iclog_header_size = BTOBB(iclog_size / XLOG_HEADER_CYCLE_SIZE);
+ } else {
+ iclog_size = XLOG_BIG_RECORD_BSIZE;
+ iclog_header_size = BBSIZE;
+ }
+
+ /*
+ * Permanent reservations have up to 'cnt'-1 active log operations
+ * in the log. A unit in this case is the amount of space for one
+ * of these log operations. Normal reservations have a cnt of 1
+ * and their unit amount is the total amount of space required.
+ *
+ * The following lines of code account for non-transaction data
+ * which occupy space in the on-disk log.
+ *
+ * Normal form of a transaction is:
+ * <oph><trans-hdr><start-oph><reg1-oph><reg1><reg2-oph>...<commit-oph>
+ * and then there are LR hdrs, split-recs and roundoff at end of syncs.
+ *
+ * We need to account for all the leadup data and trailer data
+ * around the transaction data.
+ * And then we need to account for the worst case in terms of using
+ * more space.
+ * The worst case will happen if:
+ * - the placement of the transaction happens to be such that the
+ * roundoff is at its maximum
+ * - the transaction data is synced before the commit record is synced
+ * i.e. <transaction-data><roundoff> | <commit-rec><roundoff>
+ * Therefore the commit record is in its own Log Record.
+ * This can happen as the commit record is called with its
+ * own region to xlog_write().
+ * This then means that in the worst case, roundoff can happen for
+ * the commit-rec as well.
+ * The commit-rec is smaller than padding in this scenario and so it is
+ * not added separately.
+ */
+
+ /* for trans header */
+ unit_bytes += sizeof(xlog_op_header_t);
+ unit_bytes += sizeof(xfs_trans_header_t);
+
+ /* for start-rec */
+ unit_bytes += sizeof(xlog_op_header_t);
+
+ /*
+ * for LR headers - the space for data in an iclog is the size minus
+ * the space used for the headers. If we use the iclog size, then we
+ * undercalculate the number of headers required.
+ *
+ * Furthermore - the addition of op headers for split-recs might
+ * increase the space required enough to require more log and op
+ * headers, so take that into account too.
+ *
+ * IMPORTANT: This reservation makes the assumption that if this
+ * transaction is the first in an iclog and hence has the LR headers
+ * accounted to it, then the remaining space in the iclog is
+ * exclusively for this transaction. i.e. if the transaction is larger
+ * than the iclog, it will be the only thing in that iclog.
+ * Fundamentally, this means we must pass the entire log vector to
+ * xlog_write to guarantee this.
+ */
+ iclog_space = iclog_size - iclog_header_size;
+ num_headers = howmany(unit_bytes, iclog_space);
+
+ /* for split-recs - ophdrs added when data split over LRs */
+ unit_bytes += sizeof(xlog_op_header_t) * num_headers;
+
+ /* add extra header reservations if we overrun */
+ while (!num_headers ||
+ howmany(unit_bytes, iclog_space) > num_headers) {
+ unit_bytes += sizeof(xlog_op_header_t);
+ num_headers++;
+ }
+ unit_bytes += iclog_header_size * num_headers;
+
+ /* for commit-rec LR header - note: padding will subsume the ophdr */
+ unit_bytes += iclog_header_size;
+
+ /* for roundoff padding for transaction data and one for commit record */
+ if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) {
+ /* log su roundoff */
+ unit_bytes += 2 * mp->m_sb.sb_logsunit;
+ } else {
+ /* BB roundoff */
+ unit_bytes += 2 * BBSIZE;
+ }
+
+ return unit_bytes;
+}
+
+/*
* Change the requested timestamp in the given inode.
*
* This was once shared with the kernel, but has diverged to the point
diff --git a/libxfs/xfs_log_rlimit.c b/libxfs/xfs_log_rlimit.c
new file mode 100644
index 0000000..5b5edc5
--- /dev/null
+++ b/libxfs/xfs_log_rlimit.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013 Jie Liu.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <xfs.h>
+
+/*
+ * Calculate the maximum length in bytes that would be required for a local
+ * attribute value as large attributes out of line are not logged.
+ */
+STATIC int
+xfs_log_calc_max_attrsetm_res(
+ struct xfs_mount *mp)
+{
+ int size;
+ int nblks;
+
+ size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) -
+ MAXNAMELEN - 1;
+ nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
+ nblks += XFS_B_TO_FSB(mp, size);
+ nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK);
+
+ return M_RES(mp)->tr_attrsetm.tr_logres +
+ M_RES(mp)->tr_attrsetrt.tr_logres * nblks;
+}
+
+/*
+ * Iterate over the log space reservation table to figure out and return
+ * the maximum one in terms of the pre-calculated values which were done
+ * at mount time.
+ */
+STATIC void
+xfs_log_get_max_trans_res(
+ struct xfs_mount *mp,
+ struct xfs_trans_res *max_resp)
+{
+ struct xfs_trans_res *resp;
+ struct xfs_trans_res *end_resp;
+ int log_space = 0;
+ int attr_space;
+
+ attr_space = xfs_log_calc_max_attrsetm_res(mp);
+
+ resp = (struct xfs_trans_res *)M_RES(mp);
+ end_resp = (struct xfs_trans_res *)(M_RES(mp) + 1);
+ for (; resp < end_resp; resp++) {
+ int tmp = resp->tr_logcount > 1 ?
+ resp->tr_logres * resp->tr_logcount :
+ resp->tr_logres;
+ if (log_space < tmp) {
+ log_space = tmp;
+ *max_resp = *resp; /* struct copy */
+ }
+ }
+
+ if (attr_space > log_space) {
+ *max_resp = M_RES(mp)->tr_attrsetm; /* struct copy */
+ max_resp->tr_logres = attr_space;
+ }
+}
+
+
+/*
+ * Calculate the minimum valid log size for the given superblock configuration.
+ * Used to calculate the minimum log size at mkfs time, and to determine if
+ * the log is large enough or not at mount time. Returns the minimum size in
+ * filesystem block size units.
+ */
+int
+xfs_log_calc_minimum_size(
+ struct xfs_mount *mp)
+{
+ struct xfs_trans_res tres = {0};
+ int max_logres;
+ int min_logblks = 0;
+ int lsunit = 0;
+
+ xfs_log_get_max_trans_res(mp, &tres);
+
+ max_logres = xfs_log_calc_unit_res(mp, tres.tr_logres);
+ if (tres.tr_logcount > 1)
+ max_logres *= tres.tr_logcount;
+
+ if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1)
+ lsunit = BTOBB(mp->m_sb.sb_logsunit);
+
+ /*
+ * Two factors should be taken into account for calculating the minimum
+ * log space.
+ * 1) The fundamental limitation is that no single transaction can be
+ * larger than half size of the log.
+ *
+ * From mkfs.xfs, this is considered by the XFS_MIN_LOG_FACTOR
+ * define, which is set to 3. That means we can definitely fit
+ * maximally sized 2 transactions in the log. We'll use this same
+ * value here.
+ *
+ * 2) If the lsunit option is specified, a transaction requires 2 LSU
+ * for the reservation because there are two log writes that can
+ * require padding - the transaction data and the commit record which
+ * are written separately and both can require padding to the LSU.
+ * Consider that we can have an active CIL reservation holding 2*LSU,
+ * but the CIL is not over a push threshold, in this case, if we
+ * don't have enough log space for at one new transaction, which
+ * includes another 2*LSU in the reservation, we will run into dead
+ * loop situation in log space grant procedure. i.e.
+ * xlog_grant_head_wait().
+ *
+ * Hence the log size needs to be able to contain two maximally sized
+ * and padded transactions, which is (2 * (2 * LSU + maxlres)).
+ *
+ * Also, the log size should be a multiple of the log stripe unit, round
+ * it up to lsunit boundary if lsunit is specified.
+ */
+ if (lsunit)
+ min_logblks = roundup(BTOBB(max_logres), lsunit) + 2 * lsunit;
+ else
+ min_logblks = BTOBB(max_logres);
+ min_logblks *= XFS_MIN_LOG_FACTOR;
+ return XFS_BB_TO_FSB(mp, min_logblks);
+}
diff --git a/mkfs/maxtrres.c b/mkfs/maxtrres.c
index 59cdcfd..c8cb025 100644
--- a/mkfs/maxtrres.c
+++ b/mkfs/maxtrres.c
@@ -27,46 +27,6 @@
#include <xfs/libxfs.h>
#include "xfs_mkfs.h"
-static void
-max_attrsetm_trans_res_adjust(
- xfs_mount_t *mp)
-{
- int local;
- int size;
- int nblks;
- int res;
-
- /*
- * Determine space the maximal sized attribute will use,
- * to calculate the largest reservation size needed.
- */
- size = libxfs_attr_leaf_newentsize(MAXNAMELEN, 64 * 1024,
- mp->m_sb.sb_blocksize, &local);
- ASSERT(!local);
- nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
- nblks += XFS_B_TO_FSB(mp, size);
- nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK);
- res = M_RES(mp)->tr_attrsetm.tr_logres +
- M_RES(mp)->tr_attrsetrt.tr_logres * nblks;
- M_RES(mp)->tr_attrsetm.tr_logres = res;
-}
-
-static int
-max_trans_res_by_mount(
- struct xfs_mount *mp)
-{
- struct xfs_trans_resv *tr = &mp->m_resv;
- struct xfs_trans_res *p;
- struct xfs_trans_res rval = {0};
-
- for (p = (struct xfs_trans_res *)tr;
- p < (struct xfs_trans_res *)(tr + 1); p++) {
- if (p->tr_logres > rval.tr_logres)
- rval = *p;
- }
- return rval.tr_logres;
-}
-
int
max_trans_res(
int crcs_enabled,
@@ -74,11 +34,12 @@ max_trans_res(
int sectorlog,
int blocklog,
int inodelog,
- int dirblocklog)
+ int dirblocklog,
+ int log_sunit)
{
xfs_sb_t *sbp;
xfs_mount_t mount;
- int maxres, maxfsb;
+ int maxfsb;
memset(&mount, 0, sizeof(mount));
sbp = &mount.m_sb;
@@ -93,19 +54,22 @@ max_trans_res(
sbp->sb_inodesize = 1 << inodelog;
sbp->sb_inopblock = 1 << (blocklog - inodelog);
sbp->sb_dirblklog = dirblocklog - blocklog;
+
+ log_sunit = (log_sunit == 0) ? 1 : XFS_FSB_TO_B(&mount, log_sunit);
+ sbp->sb_logsunit = log_sunit;
sbp->sb_versionnum =
(crcs_enabled ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) |
- (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0);
+ (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0) |
+ (log_sunit > 1 ? XFS_SB_VERSION_LOGV2BIT : 0);
libxfs_mount(&mount, sbp, 0,0,0,0);
- max_attrsetm_trans_res_adjust(&mount);
- maxres = max_trans_res_by_mount(&mount);
- maxfsb = XFS_B_TO_FSB(&mount, maxres);
+ maxfsb = xfs_log_calc_minimum_size(&mount);
libxfs_umount(&mount);
#if 0
- printf("#define\tMAXTRRES_S%d_B%d_I%d_D%d_V%d\t%lld\n",
- sectorlog, blocklog, inodelog, dirblocklog, dirversion, maxfsb);
+ printf("#define\tMAXTRRES_S%d_B%d_I%d_D%d_V%d_LSU%d\t%d\n",
+ sectorlog, blocklog, inodelog, dirblocklog, dirversion,
+ log_sunit, maxfsb);
#endif
return maxfsb;
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index a940150..62e4d27 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2111,50 +2111,6 @@ reported by the device (%u).\n"),
sectorsize, xi.rtbsize);
}
- max_tr_res = max_trans_res(crcs_enabled, dirversion,
- sectorlog, blocklog, inodelog, dirblocklog);
- ASSERT(max_tr_res);
- min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR;
- min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
- if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
- min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
- if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
- fprintf(stderr,
-_("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
- logsize, (long long)DTOBT(xi.logBBsize));
- usage();
- } else if (!logsize && xi.logBBsize > 0) {
- logblocks = DTOBT(xi.logBBsize);
- } else if (logsize && !xi.logdev && !loginternal) {
- fprintf(stderr,
- _("size specified for non-existent log subvolume\n"));
- usage();
- } else if (loginternal && logsize && logblocks >= dblocks) {
- fprintf(stderr, _("size %lld too large for internal log\n"),
- (long long)logblocks);
- usage();
- } else if (!loginternal && !xi.logdev) {
- logblocks = 0;
- } else if (loginternal && !logsize) {
- /*
- * With a 2GB max log size, default to maximum size
- * at 4TB. This keeps the same ratio from the older
- * max log size of 128M at 256GB fs size. IOWs,
- * the ratio of fs size to log size is 2048:1.
- */
- logblocks = (dblocks << blocklog) / 2048;
- logblocks = logblocks >> blocklog;
- logblocks = MAX(min_logblocks, logblocks);
- logblocks = MAX(logblocks,
- MAX(XFS_DFL_LOG_SIZE,
- max_tr_res * XFS_DFL_LOG_FACTOR));
- logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
- if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
- logblocks = XFS_MAX_LOG_BYTES >> blocklog;
- }
- }
- validate_log_size(logblocks, blocklog, min_logblocks);
-
if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
fprintf(stderr,
_("size %s specified for rt subvolume is too large, "
@@ -2363,6 +2319,51 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
fprintf(stderr, _("log stripe unit adjusted to 32KiB\n"));
}
+ max_tr_res = max_trans_res(crcs_enabled, dirversion,
+ sectorlog, blocklog, inodelog, dirblocklog,
+ lsunit);
+ ASSERT(max_tr_res);
+ min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR;
+ min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
+ if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
+ min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
+ if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
+ fprintf(stderr,
+_("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
+ logsize, (long long)DTOBT(xi.logBBsize));
+ usage();
+ } else if (!logsize && xi.logBBsize > 0) {
+ logblocks = DTOBT(xi.logBBsize);
+ } else if (logsize && !xi.logdev && !loginternal) {
+ fprintf(stderr,
+ _("size specified for non-existent log subvolume\n"));
+ usage();
+ } else if (loginternal && logsize && logblocks >= dblocks) {
+ fprintf(stderr, _("size %lld too large for internal log\n"),
+ (long long)logblocks);
+ usage();
+ } else if (!loginternal && !xi.logdev) {
+ logblocks = 0;
+ } else if (loginternal && !logsize) {
+ /*
+ * With a 2GB max log size, default to maximum size
+ * at 4TB. This keeps the same ratio from the older
+ * max log size of 128M at 256GB fs size. IOWs,
+ * the ratio of fs size to log size is 2048:1.
+ */
+ logblocks = (dblocks << blocklog) / 2048;
+ logblocks = logblocks >> blocklog;
+ logblocks = MAX(min_logblocks, logblocks);
+ logblocks = MAX(logblocks,
+ MAX(XFS_DFL_LOG_SIZE,
+ max_tr_res * XFS_DFL_LOG_FACTOR));
+ logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
+ if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
+ logblocks = XFS_MAX_LOG_BYTES >> blocklog;
+ }
+ }
+ validate_log_size(logblocks, blocklog, min_logblocks);
+
protostring = setup_proto(protofile);
bsize = 1 << (blocklog - BBSHIFT);
mp = &mbuf;
@@ -2371,6 +2372,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
sbp->sb_blocklog = (__uint8_t)blocklog;
sbp->sb_sectlog = (__uint8_t)sectorlog;
sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize);
+ sbp->sb_agblocks = (xfs_agblock_t)agsize;
mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
@@ -2382,6 +2384,9 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
if (!logsize) {
logblocks = MIN(logblocks,
XFS_ALLOC_AG_MAX_USABLE(mp));
+
+ /* revalidate the log size is valid if we changed it */
+ validate_log_size(logblocks, blocklog, min_logblocks);
}
if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
fprintf(stderr,
@@ -2389,6 +2394,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
(long long)logblocks);
usage();
}
+
if (laflag) {
if (logagno >= agcount) {
fprintf(stderr,
@@ -2457,7 +2463,6 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
sbp->sb_logstart = logstart;
sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
sbp->sb_rextsize = rtextblocks;
- sbp->sb_agblocks = (xfs_agblock_t)agsize;
sbp->sb_agcount = (xfs_agnumber_t)agcount;
sbp->sb_rbmblocks = nbmblocks;
sbp->sb_logblocks = (xfs_extlen_t)logblocks;
diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h
index d10e444..37f1667 100644
--- a/mkfs/xfs_mkfs.h
+++ b/mkfs/xfs_mkfs.h
@@ -54,7 +54,6 @@
#define XFS_MIN_REC_DIRSIZE 12 /* 4096 byte dirblocks (V2) */
#define XFS_DFL_DIR_VERSION 2 /* default directory version */
#define XFS_DFL_LOG_SIZE 1000 /* default log size, blocks */
-#define XFS_MIN_LOG_FACTOR 3 /* min log size factor */
#define XFS_DFL_LOG_FACTOR 16 /* default log size, factor */
/* with max trans reservation */
#define XFS_MAX_INODE_SIG_BITS 32 /* most significant bits in an
@@ -82,6 +81,7 @@ extern void res_failed (int err);
/* maxtrres.c */
extern int max_trans_res (int crcs_enabled, int dirversion,
- int sectorlog, int blocklog, int inodelog, int dirblocklog);
+ int sectorlog, int blocklog, int inodelog, int dirblocklog,
+ int log_sunit);
#endif /* __XFS_MKFS_H__ */
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 47/49] xfs: Add read-only support for dirent filetype field
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (45 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 46/49] xfs: Add xfs_log_rlimit.c Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-08-06 21:13 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 48/49] xfs: Add write " Dave Chinner
` (2 subsequent siblings)
49 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Add support for the file type field in directory entries so that
readdir can return the type of the inode the dirent points to to
userspace without first having to read the inode off disk.
The encoding of the type field is a single byte that is added to the
end of the directory entry name length. For all intents and
purposes, it appends a "hidden" byte to the name field which
contains the type information. As the directory entry is already of
dynamic size, helpers are already required to access and decode the
direct entry structures.
Hence the relevent extraction and iteration helpers are updated to
understand the hidden byte. Helpers for reading and writing the
filetype field from the directory entries are also added. Only the
read helpers are used by this patch. It also adds all the code
necessary to read the type information out of the dirents on disk.
Further we add the superblock feature bit and helpers to indicate
that we understand the on-disk format change. This is not a
compatible change - existing kernels cannot read the new format
successfully - so an incompatible feature flag is added. We don't
yet allow filesystems to mount with this flag yet - that will be
added once write support is added.
Finally, the code to take the type from the VFS, convert it to an
XFS on-disk type and put it into the xfs_name structures passed
around is added, but the directory code does not use this field yet.
That will be in the next patch.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
db/check.c | 12 +--
db/dir2.c | 10 +--
db/dir2sf.c | 9 ++-
db/metadump.c | 10 +--
include/xfs_da_btree.h | 1 +
include/xfs_dir2.h | 9 ++-
include/xfs_dir2_format.h | 183 ++++++++++++++++++++++++++++++++++++++++------
include/xfs_sb.h | 28 ++++---
include/xfs_types.h | 1 +
libxfs/xfs_dir2.c | 5 +-
libxfs/xfs_dir2_block.c | 18 ++---
libxfs/xfs_dir2_data.c | 13 ++--
libxfs/xfs_dir2_leaf.c | 6 +-
libxfs/xfs_dir2_node.c | 8 +-
libxfs/xfs_dir2_priv.h | 44 +++++------
libxfs/xfs_dir2_sf.c | 122 ++++++++++++++++++-------------
logprint/log_misc.c | 58 ++++++++-------
repair/dir2.c | 37 +++++-----
repair/dir2.h | 1 +
repair/phase6.c | 22 +++---
20 files changed, 384 insertions(+), 213 deletions(-)
diff --git a/db/check.c b/db/check.c
index d490f81..287e491 100644
--- a/db/check.c
+++ b/db/check.c
@@ -2309,7 +2309,7 @@ process_data_dir_v2(
(int)((char *)dep - (char *)data));
error++;
}
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
if ((char *)tagp >= endptr) {
if (!sflag || v)
dbprintf(_("dir %lld block %d bad entry at %d\n"),
@@ -2324,7 +2324,7 @@ process_data_dir_v2(
xname.name = dep->name;
xname.len = dep->namelen;
dir_hash_add(mp->m_dirnameops->hashname(&xname), addr);
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
count++;
lastfree = 0;
lino = be64_to_cpu(dep->inumber);
@@ -3434,7 +3434,7 @@ process_sf_dir_v2(
sfe = xfs_dir2_sf_firstentry(sf);
offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
for (i = sf->count - 1, i8 = 0; i >= 0; i--) {
- if ((__psint_t)sfe + xfs_dir2_sf_entsize(sf, sfe->namelen) -
+ if ((__psint_t)sfe + xfs_dir3_sf_entsize(mp, sf, sfe->namelen) -
(__psint_t)sf > be64_to_cpu(dip->di_size)) {
if (!sflag)
dbprintf(_("dir %llu bad size in entry at %d\n"),
@@ -3443,7 +3443,7 @@ process_sf_dir_v2(
error++;
break;
}
- lino = xfs_dir2_sfe_get_ino(sf, sfe);
+ lino = xfs_dir3_sfe_get_ino(mp, sf, sfe);
if (lino > XFS_DIR2_MAX_SHORT_INUM)
i8++;
cid = find_inode(lino, 1);
@@ -3473,8 +3473,8 @@ process_sf_dir_v2(
}
offset =
xfs_dir2_sf_get_offset(sfe) +
- xfs_dir2_sf_entsize(sf, sfe->namelen);
- sfe = xfs_dir2_sf_nextentry(sf, sfe);
+ xfs_dir3_sf_entsize(mp, sf, sfe->namelen);
+ sfe = xfs_dir3_sf_nextentry(mp, sf, sfe);
}
if (i < 0 && (__psint_t)sfe - (__psint_t)sf !=
be64_to_cpu(dip->di_size)) {
diff --git a/db/dir2.c b/db/dir2.c
index 85240b0..39042b3 100644
--- a/db/dir2.c
+++ b/db/dir2.c
@@ -222,7 +222,7 @@ __dir2_data_entries_count(
ptr += be16_to_cpu(dup->length);
else {
dep = (xfs_dir2_data_entry_t *)ptr;
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
}
}
return i;
@@ -246,7 +246,7 @@ __dir2_data_entry_offset(
ptr += be16_to_cpu(dup->length);
else {
dep = (xfs_dir2_data_entry_t *)ptr;
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
}
}
return ptr;
@@ -495,7 +495,7 @@ dir2_data_union_tag_count(
end = (char *)&dep->namelen + sizeof(dep->namelen);
if (end > (char *)obj + mp->m_dirblksize)
return 0;
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
}
end = (char *)tagp + sizeof(*tagp);
return end <= (char *)obj + mp->m_dirblksize;
@@ -517,7 +517,7 @@ dir2_data_union_tag_offset(
return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) -
(char *)dup));
dep = (xfs_dir2_data_entry_t *)dup;
- return bitize((int)((char *)xfs_dir2_data_entry_tag_p(dep) -
+ return bitize((int)((char *)xfs_dir3_data_entry_tag_p(mp, dep) -
(char *)dep));
}
@@ -592,7 +592,7 @@ dir2_data_union_size(
return bitize(be16_to_cpu(dup->length));
else {
dep = (xfs_dir2_data_entry_t *)dup;
- return bitize(xfs_dir2_data_entsize(dep->namelen));
+ return bitize(xfs_dir3_data_entsize(mp, dep->namelen));
}
}
diff --git a/db/dir2sf.c b/db/dir2sf.c
index b32ca32..d628641 100644
--- a/db/dir2sf.c
+++ b/db/dir2sf.c
@@ -24,6 +24,7 @@
#include "bit.h"
#include "dir2.h"
#include "dir2sf.h"
+#include "init.h"
static int dir2_inou_i4_count(void *obj, int startoff);
static int dir2_inou_i8_count(void *obj, int startoff);
@@ -155,8 +156,8 @@ dir2_sf_entry_size(
sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
e = xfs_dir2_sf_firstentry(sf);
for (i = 0; i < idx; i++)
- e = xfs_dir2_sf_nextentry(sf, e);
- return bitize((int)xfs_dir2_sf_entsize(sf, e->namelen));
+ e = xfs_dir3_sf_nextentry(mp, sf, e);
+ return bitize((int)xfs_dir3_sf_entsize(mp, sf, e->namelen));
}
/*ARGSUSED*/
@@ -200,7 +201,7 @@ dir2_sf_list_offset(
sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
e = xfs_dir2_sf_firstentry(sf);
for (i = 0; i < idx; i++)
- e = xfs_dir2_sf_nextentry(sf, e);
+ e = xfs_dir3_sf_nextentry(mp, sf, e);
return bitize((int)((char *)e - (char *)sf));
}
@@ -220,6 +221,6 @@ dir2sf_size(
sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
e = xfs_dir2_sf_firstentry(sf);
for (i = 0; i < sf->count; i++)
- e = xfs_dir2_sf_nextentry(sf, e);
+ e = xfs_dir3_sf_nextentry(mp, sf, e);
return bitize((int)((char *)e - (char *)sf));
}
diff --git a/db/metadump.c b/db/metadump.c
index 1c8020b..d9f35b0 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -939,7 +939,7 @@ obfuscate_sf_dir(
namelen = ino_dir_size - ((char *)&sfep->name[0] -
(char *)sfp);
} else if ((char *)sfep - (char *)sfp +
- xfs_dir2_sf_entsize(sfp, sfep->namelen) >
+ xfs_dir3_sf_entsize(mp, sfp, sfep->namelen) >
ino_dir_size) {
if (show_warnings)
print_warning("entry length in dir inode %llu "
@@ -950,11 +950,11 @@ obfuscate_sf_dir(
(char *)sfp);
}
- generate_obfuscated_name(xfs_dir2_sfe_get_ino(sfp, sfep),
+ generate_obfuscated_name(xfs_dir3_sfe_get_ino(mp, sfp, sfep),
namelen, &sfep->name[0]);
sfep = (xfs_dir2_sf_entry_t *)((char *)sfep +
- xfs_dir2_sf_entsize(sfp, namelen));
+ xfs_dir3_sf_entsize(mp, sfp, namelen));
}
}
@@ -1184,7 +1184,7 @@ obfuscate_dir_data_blocks(
}
dep = (xfs_dir2_data_entry_t *)ptr;
- length = xfs_dir2_data_entsize(dep->namelen);
+ length = xfs_dir3_data_entsize(mp, dep->namelen);
if (dir_offset + length > dir_data.end_of_data ||
ptr + length > endptr) {
@@ -1194,7 +1194,7 @@ obfuscate_dir_data_blocks(
(long long)cur_ino);
break;
}
- if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) !=
+ if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) !=
dir_offset) {
dir_data.bad_block = 1;
break;
diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h
index 6fb3371..8cdc77b 100644
--- a/include/xfs_da_btree.h
+++ b/include/xfs_da_btree.h
@@ -176,6 +176,7 @@ enum xfs_dacmp {
typedef struct xfs_da_args {
const __uint8_t *name; /* string (maybe not NULL terminated) */
int namelen; /* length of string (maybe no NULL) */
+ __uint8_t filetype; /* filetype of inode for directories */
__uint8_t *value; /* set of bytes (maybe contain NULLs) */
int valuelen; /* length of value */
int flags; /* argument flags (eg: ATTR_NOCREATE) */
diff --git a/include/xfs_dir2.h b/include/xfs_dir2.h
index 7fe2b8f..9910401 100644
--- a/include/xfs_dir2.h
+++ b/include/xfs_dir2.h
@@ -68,10 +68,11 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
extern void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *sfp,
xfs_ino_t ino);
-extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
- struct xfs_dir2_sf_entry *sfep);
-extern void xfs_dir2_sfe_put_ino( struct xfs_dir2_sf_hdr *,
- struct xfs_dir2_sf_entry *sfep, xfs_ino_t ino);
+extern xfs_ino_t xfs_dir3_sfe_get_ino(struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *sfp, struct xfs_dir2_sf_entry *sfep);
+extern void xfs_dir3_sfe_put_ino(struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep,
+ xfs_ino_t ino);
extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
diff --git a/include/xfs_dir2_format.h b/include/xfs_dir2_format.h
index 2095e17..a0961a6 100644
--- a/include/xfs_dir2_format.h
+++ b/include/xfs_dir2_format.h
@@ -69,6 +69,23 @@
#define XFS_DIR3_FREE_MAGIC 0x58444633 /* XDF3: free index blocks */
/*
+ * Dirents in version 3 directories have a file type field. Additions to this
+ * list are an on-disk format change, requiring feature bits. Valid values
+ * are as follows:
+ */
+#define XFS_DIR3_FT_UNKNOWN 0
+#define XFS_DIR3_FT_REG_FILE 1
+#define XFS_DIR3_FT_DIR 2
+#define XFS_DIR3_FT_CHRDEV 3
+#define XFS_DIR3_FT_BLKDEV 4
+#define XFS_DIR3_FT_FIFO 5
+#define XFS_DIR3_FT_SOCK 6
+#define XFS_DIR3_FT_SYMLINK 7
+#define XFS_DIR3_FT_WHT 8
+
+#define XFS_DIR3_FT_MAX 9
+
+/*
* Byte offset in data block and shortform entry.
*/
typedef __uint16_t xfs_dir2_data_off_t;
@@ -138,6 +155,9 @@ typedef struct xfs_dir2_sf_entry {
xfs_dir2_sf_off_t offset; /* saved offset */
__u8 name[]; /* name, variable size */
/*
+ * A single byte containing the file type field follows the inode
+ * number for version 3 directory entries.
+ *
* A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
* variable offset after the name.
*/
@@ -162,16 +182,6 @@ xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
put_unaligned_be16(off, &sfep->offset.i);
}
-static inline int
-xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
-{
- return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
- len + /* name */
- (hdr->i8count ? /* ino */
- sizeof(xfs_dir2_ino8_t) :
- sizeof(xfs_dir2_ino4_t));
-}
-
static inline struct xfs_dir2_sf_entry *
xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
{
@@ -179,14 +189,78 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
}
+static inline int
+xfs_dir3_sf_entsize(
+ struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *hdr,
+ int len)
+{
+ int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */
+
+ count += len; /* name */
+ count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) :
+ sizeof(xfs_dir2_ino4_t); /* ino # */
+ if (xfs_sb_version_hasftype(&mp->m_sb))
+ count += sizeof(__uint8_t); /* file type */
+ return count;
+}
+
static inline struct xfs_dir2_sf_entry *
-xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
- struct xfs_dir2_sf_entry *sfep)
+xfs_dir3_sf_nextentry(
+ struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *hdr,
+ struct xfs_dir2_sf_entry *sfep)
{
return (struct xfs_dir2_sf_entry *)
- ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
+ ((char *)sfep + xfs_dir3_sf_entsize(mp, hdr, sfep->namelen));
}
+/*
+ * in dir3 shortform directories, the file type field is stored at a variable
+ * offset after the inode number. Because it's only a single byte, endian
+ * conversion is not necessary.
+ */
+static inline __uint8_t *
+xfs_dir3_sfe_ftypep(
+ struct xfs_dir2_sf_hdr *hdr,
+ struct xfs_dir2_sf_entry *sfep)
+{
+ return (__uint8_t *)&sfep->name[sfep->namelen];
+}
+
+static inline __uint8_t
+xfs_dir3_sfe_get_ftype(
+ struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *hdr,
+ struct xfs_dir2_sf_entry *sfep)
+{
+ __uint8_t *ftp;
+
+ if (!xfs_sb_version_hasftype(&mp->m_sb))
+ return XFS_DIR3_FT_UNKNOWN;
+
+ ftp = xfs_dir3_sfe_ftypep(hdr, sfep);
+ if (*ftp >= XFS_DIR3_FT_MAX)
+ return XFS_DIR3_FT_UNKNOWN;
+ return *ftp;
+}
+
+static inline void
+xfs_dir3_sfe_put_ftype(
+ struct xfs_mount *mp,
+ struct xfs_dir2_sf_hdr *hdr,
+ struct xfs_dir2_sf_entry *sfep,
+ __uint8_t ftype)
+{
+ __uint8_t *ftp;
+
+ ASSERT(ftype < XFS_DIR3_FT_MAX);
+
+ if (!xfs_sb_version_hasftype(&mp->m_sb))
+ return;
+ ftp = xfs_dir3_sfe_ftypep(hdr, sfep);
+ *ftp = ftype;
+}
/*
* Data block structures.
@@ -286,12 +360,18 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
* Active entry in a data block.
*
* Aligned to 8 bytes. After the variable length name field there is a
- * 2 byte tag field, which can be accessed using xfs_dir2_data_entry_tag_p.
+ * 2 byte tag field, which can be accessed using xfs_dir3_data_entry_tag_p.
+ *
+ * For dir3 structures, there is file type field between the name and the tag.
+ * This can only be manipulated by helper functions. It is packed hard against
+ * the end of the name so any padding for rounding is between the file type and
+ * the tag.
*/
typedef struct xfs_dir2_data_entry {
__be64 inumber; /* inode number */
__u8 namelen; /* name length */
__u8 name[]; /* name bytes, no null */
+ /* __u8 filetype; */ /* type of inode we point to */
/* __be16 tag; */ /* starting offset of us */
} xfs_dir2_data_entry_t;
@@ -311,20 +391,67 @@ typedef struct xfs_dir2_data_unused {
/*
* Size of a data entry.
*/
-static inline int xfs_dir2_data_entsize(int n)
+static inline int
+__xfs_dir3_data_entsize(
+ bool ftype,
+ int n)
{
- return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
- (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
+ int size = offsetof(struct xfs_dir2_data_entry, name[0]);
+
+ size += n;
+ size += sizeof(xfs_dir2_data_off_t);
+ if (ftype)
+ size += sizeof(__uint8_t);
+ return roundup(size, XFS_DIR2_DATA_ALIGN);
+}
+static inline int
+xfs_dir3_data_entsize(
+ struct xfs_mount *mp,
+ int n)
+{
+ bool ftype = xfs_sb_version_hasftype(&mp->m_sb) ? true : false;
+ return __xfs_dir3_data_entsize(ftype, n);
+}
+
+static inline __uint8_t
+xfs_dir3_dirent_get_ftype(
+ struct xfs_mount *mp,
+ struct xfs_dir2_data_entry *dep)
+{
+ if (xfs_sb_version_hasftype(&mp->m_sb)) {
+ __uint8_t type = dep->name[dep->namelen];
+
+ ASSERT(type < XFS_DIR3_FT_MAX);
+ if (type < XFS_DIR3_FT_MAX)
+ return type;
+
+ }
+ return XFS_DIR3_FT_UNKNOWN;
+}
+
+static inline void
+xfs_dir3_dirent_put_ftype(
+ struct xfs_mount *mp,
+ struct xfs_dir2_data_entry *dep,
+ __uint8_t type)
+{
+ ASSERT(type < XFS_DIR3_FT_MAX);
+ ASSERT(dep->namelen != 0);
+
+ if (xfs_sb_version_hasftype(&mp->m_sb))
+ dep->name[dep->namelen] = type;
}
/*
* Pointer to an entry's tag word.
*/
static inline __be16 *
-xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
+xfs_dir3_data_entry_tag_p(
+ struct xfs_mount *mp,
+ struct xfs_dir2_data_entry *dep)
{
return (__be16 *)((char *)dep +
- xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
+ xfs_dir3_data_entsize(mp, dep->namelen) - sizeof(__be16));
}
/*
@@ -375,13 +502,17 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
* data block header because the sfe embeds the block offset of the entry into
* it so that it doesn't change when format conversion occurs. Bad Things Happen
* if we don't follow this rule.
+ *
+ * XXX: there is scope for significant optimisation of the logic here. Right
+ * now we are checking for "dir3 format" over and over again. Ideally we should
+ * only do it once for each operation.
*/
#define XFS_DIR3_DATA_DOT_OFFSET(mp) \
xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
#define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
- (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir2_data_entsize(1))
+ (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 1))
#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
- (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir2_data_entsize(2))
+ (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2))
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
@@ -392,13 +523,19 @@ xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr)
{
- return xfs_dir3_data_dot_offset(hdr) + xfs_dir2_data_entsize(1);
+ bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
+ hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
+ return xfs_dir3_data_dot_offset(hdr) +
+ __xfs_dir3_data_entsize(dir3, 1);
}
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr)
{
- return xfs_dir3_data_dotdot_offset(hdr) + xfs_dir2_data_entsize(2);
+ bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
+ hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
+ return xfs_dir3_data_dotdot_offset(hdr) +
+ __xfs_dir3_data_entsize(dir3, 2);
}
/*
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index d6f3648..c5b1c04 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -555,12 +555,6 @@ static inline void xfs_sb_version_addprojid32bit(xfs_sb_t *sbp)
sbp->sb_bad_features2 |= XFS_SB_VERSION2_PROJID32BIT;
}
-static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
-}
-
-
/*
* Extended v5 superblock feature masks. These are to be used for new v5
* superblock features only.
@@ -599,7 +593,9 @@ xfs_sb_has_ro_compat_feature(
return (sbp->sb_features_ro_compat & feature) != 0;
}
+#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_ALL 0
+
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool
xfs_sb_has_incompat_feature(
@@ -619,16 +615,30 @@ xfs_sb_has_incompat_log_feature(
return (sbp->sb_features_log_incompat & feature) != 0;
}
-static inline bool
-xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
+/*
+ * V5 superblock specific feature checks
+ */
+static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp)
{
- return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
+}
+
+static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
+{
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+ xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_FTYPE);
}
/*
* end of superblock version macros
*/
+static inline bool
+xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
+{
+ return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
+}
+
#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)((bp)->b_addr))
diff --git a/include/xfs_types.h b/include/xfs_types.h
index ce44b18..82bbc34 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -140,6 +140,7 @@ typedef enum {
struct xfs_name {
const unsigned char *name;
int len;
+ int type;
};
/*
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 830fe3e..521042f 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -18,7 +18,8 @@
#include <xfs.h>
-struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2};
+struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
+
/*
* ASCII case-insensitive (ie. A-Z) support for directories that was
@@ -367,6 +368,7 @@ xfs_dir_replace(
memset(&args, 0, sizeof(xfs_da_args_t));
args.name = name->name;
args.namelen = name->len;
+ args.filetype = name->type;
args.hashval = dp->i_mount->m_dirnameops->hashname(name);
args.inumber = inum;
args.dp = dp;
@@ -414,6 +416,7 @@ xfs_dir_canenter(
memset(&args, 0, sizeof(xfs_da_args_t));
args.name = name->name;
args.namelen = name->len;
+ args.filetype = name->type;
args.hashval = dp->i_mount->m_dirnameops->hashname(name);
args.dp = dp;
args.whichfork = XFS_DATA_FORK;
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index d94b9b2..615eea9 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -107,7 +107,7 @@ const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
.verify_write = xfs_dir3_block_write_verify,
};
-static int
+int
xfs_dir3_block_read(
struct xfs_trans *tp,
struct xfs_inode *dp,
@@ -350,7 +350,7 @@ xfs_dir2_block_addname(
if (error)
return error;
- len = xfs_dir2_data_entsize(args->namelen);
+ len = xfs_dir3_data_entsize(mp, args->namelen);
/*
* Set up pointers to parts of the block.
@@ -530,7 +530,7 @@ xfs_dir2_block_addname(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, args->namelen);
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
/*
* Clean up the bestfree array and log the header, tail, and entry.
@@ -780,7 +780,7 @@ xfs_dir2_block_removename(
needlog = needscan = 0;
xfs_dir2_data_make_free(tp, bp,
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
- xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
+ xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan);
/*
* Fix up the block tail.
*/
@@ -1140,7 +1140,7 @@ xfs_dir2_sf_to_block(
dep->inumber = cpu_to_be64(dp->i_ino);
dep->namelen = 1;
dep->name[0] = '.';
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, bp, dep);
blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
@@ -1153,7 +1153,7 @@ xfs_dir2_sf_to_block(
dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
dep->namelen = 2;
dep->name[0] = dep->name[1] = '.';
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, bp, dep);
blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
@@ -1198,10 +1198,10 @@ xfs_dir2_sf_to_block(
* Copy a real entry.
*/
dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
- dep->inumber = cpu_to_be64(xfs_dir2_sfe_get_ino(sfp, sfep));
+ dep->inumber = cpu_to_be64(xfs_dir3_sfe_get_ino(mp, sfp, sfep));
dep->namelen = sfep->namelen;
memcpy(dep->name, sfep->name, dep->namelen);
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, bp, dep);
name.name = sfep->name;
@@ -1214,7 +1214,7 @@ xfs_dir2_sf_to_block(
if (++i == sfp->count)
sfep = NULL;
else
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
}
/* Done with the temporary buffer */
kmem_free(sfp);
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index 5074878..ea9ba91 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -131,7 +131,7 @@ __xfs_dir3_data_check(
XFS_WANT_CORRUPTED_RETURN(
!xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)));
XFS_WANT_CORRUPTED_RETURN(
- be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) ==
+ be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) ==
(char *)dep - (char *)hdr);
count++;
lastfree = 0;
@@ -150,7 +150,7 @@ __xfs_dir3_data_check(
}
XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count));
}
- p += xfs_dir2_data_entsize(dep->namelen);
+ p += xfs_dir3_data_entsize(mp, dep->namelen);
}
/*
* Need to have seen all the entries and all the bestfree slots.
@@ -520,8 +520,8 @@ xfs_dir2_data_freescan(
else {
dep = (xfs_dir2_data_entry_t *)p;
ASSERT((char *)dep - (char *)hdr ==
- be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)));
- p += xfs_dir2_data_entsize(dep->namelen);
+ be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)));
+ p += xfs_dir3_data_entsize(mp, dep->namelen);
}
}
}
@@ -611,7 +611,8 @@ xfs_dir2_data_log_entry(
struct xfs_buf *bp,
xfs_dir2_data_entry_t *dep) /* data entry pointer */
{
- xfs_dir2_data_hdr_t *hdr = bp->b_addr;
+ struct xfs_dir2_data_hdr *hdr = bp->b_addr;
+ struct xfs_mount *mp = tp->t_mountp;
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -619,7 +620,7 @@ xfs_dir2_data_log_entry(
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr),
- (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) -
+ (uint)((char *)(xfs_dir3_data_entry_tag_p(mp, dep) + 1) -
(char *)hdr - 1));
}
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index 55b7d05..04ad083 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -677,7 +677,7 @@ xfs_dir2_leaf_addname(
ents = xfs_dir3_leaf_ents_p(leaf);
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
bestsp = xfs_dir2_leaf_bests_p(ltp);
- length = xfs_dir2_data_entsize(args->namelen);
+ length = xfs_dir3_data_entsize(mp, args->namelen);
/*
* See if there are any entries with the same hash value
@@ -878,7 +878,7 @@ xfs_dir2_leaf_addname(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
/*
* Need to scan fix up the bestfree table.
@@ -1409,7 +1409,7 @@ xfs_dir2_leaf_removename(
*/
xfs_dir2_data_make_free(tp, dbp,
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
- xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
+ xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan);
/*
* We just mark the leaf entry stale by putting a null in it.
*/
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index d2bd249..5b118d5 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -587,7 +587,7 @@ xfs_dir2_leafn_lookup_for_addname(
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
}
- length = xfs_dir2_data_entsize(args->namelen);
+ length = xfs_dir3_data_entsize(mp, args->namelen);
/*
* Loop over leaf entries with the right hash value.
*/
@@ -1241,7 +1241,7 @@ xfs_dir2_leafn_remove(
longest = be16_to_cpu(bf[0].length);
needlog = needscan = 0;
xfs_dir2_data_make_free(tp, dbp, off,
- xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
+ xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan);
/*
* Rescan the data block freespaces for bestfree.
* Log the data block header if needed.
@@ -1693,7 +1693,7 @@ xfs_dir2_node_addname_int(
dp = args->dp;
mp = dp->i_mount;
tp = args->trans;
- length = xfs_dir2_data_entsize(args->namelen);
+ length = xfs_dir3_data_entsize(mp, args->namelen);
/*
* If we came in with a freespace block that means that lookup
* found an entry with our hash value. This is the freespace
@@ -1989,7 +1989,7 @@ xfs_dir2_node_addname_int(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
- tagp = xfs_dir2_data_entry_tag_p(dep);
+ tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dbp, dep);
/*
diff --git a/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h
index 7af3e92..1bad84c 100644
--- a/libxfs/xfs_dir2_priv.h
+++ b/libxfs/xfs_dir2_priv.h
@@ -18,21 +18,26 @@
#ifndef __XFS_DIR2_PRIV_H__
#define __XFS_DIR2_PRIV_H__
+struct dir_context;
+
/* xfs_dir2.c */
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
-extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
-extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
xfs_dir2_db_t *dbp);
-extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
- struct xfs_buf *bp);
extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
const unsigned char *name, int len);
+#define S_SHIFT 12
+extern const unsigned char xfs_mode_to_ftype[];
+
+extern unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp,
+ __uint8_t filetype);
+
+
/* xfs_dir2_block.c */
+extern int xfs_dir3_block_read(struct xfs_trans *tp, struct xfs_inode *dp,
+ struct xfs_buf **bpp);
extern int xfs_dir2_block_addname(struct xfs_da_args *args);
-extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
- xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
extern int xfs_dir2_block_removename(struct xfs_da_args *args);
extern int xfs_dir2_block_replace(struct xfs_da_args *args);
@@ -55,22 +60,8 @@ extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp,
extern struct xfs_dir2_data_free *
xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
struct xfs_dir2_data_unused *dup, int *loghead);
-extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
- struct xfs_dir2_data_hdr *hdr, int *loghead);
extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
struct xfs_buf **bpp);
-extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_dir2_data_entry *dep);
-extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
- struct xfs_buf *bp);
-extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_dir2_data_unused *dup);
-extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_buf *bp,
- xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
- int *needlogp, int *needscanp);
-extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset,
- xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
/* xfs_dir2_leaf.c */
extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
@@ -83,8 +74,6 @@ extern void xfs_dir3_leaf_compact(struct xfs_da_args *args,
extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
struct xfs_dir2_leaf_entry *ents, int *indexp,
int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
-extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
- size_t bufsize, xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
struct xfs_buf **bpp, __uint16_t magic);
extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp,
@@ -104,6 +93,8 @@ xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr,
int lowstale, int highstale, int *lfloglow, int *lfloghigh);
extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
+extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to,
+ struct xfs_dir2_leaf *from);
extern void xfs_dir3_leaf_hdr_to_disk(struct xfs_dir2_leaf *to,
struct xfs_dir3_icleaf_hdr *from);
extern bool xfs_dir3_leaf_check_int(struct xfs_mount *mp,
@@ -134,19 +125,18 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_dablk_t fbno, struct xfs_buf **bpp);
/* xfs_dir2_sf.c */
-extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
-extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
- struct xfs_dir2_sf_entry *sfep);
extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
int size, xfs_dir2_sf_hdr_t *sfhp);
extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
-extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
- xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
+/* xfs_dir2_readdir.c */
+extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx,
+ size_t bufsize);
+
#endif /* __XFS_DIR2_PRIV_H__ */
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index cb23368..2791d99 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -15,7 +15,6 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
/*
@@ -89,31 +88,38 @@ xfs_dir2_sf_put_parent_ino(
/*
* In short-form directory entries the inode numbers are stored at variable
- * offset behind the entry name. The inode numbers may only be accessed
- * through the helpers below.
+ * offset behind the entry name. If the entry stores a filetype value, then it
+ * sits between the name and the inode number. Hence the inode numbers may only
+ * be accessed through the helpers below.
*/
static xfs_dir2_inou_t *
-xfs_dir2_sfe_inop(
+xfs_dir3_sfe_inop(
+ struct xfs_mount *mp,
struct xfs_dir2_sf_entry *sfep)
{
- return (xfs_dir2_inou_t *)&sfep->name[sfep->namelen];
+ __uint8_t *ptr = &sfep->name[sfep->namelen];
+ if (xfs_sb_version_hasftype(&mp->m_sb))
+ ptr++;
+ return (xfs_dir2_inou_t *)ptr;
}
xfs_ino_t
-xfs_dir2_sfe_get_ino(
+xfs_dir3_sfe_get_ino(
+ struct xfs_mount *mp,
struct xfs_dir2_sf_hdr *hdr,
struct xfs_dir2_sf_entry *sfep)
{
- return xfs_dir2_sf_get_ino(hdr, xfs_dir2_sfe_inop(sfep));
+ return xfs_dir2_sf_get_ino(hdr, xfs_dir3_sfe_inop(mp, sfep));
}
void
-xfs_dir2_sfe_put_ino(
+xfs_dir3_sfe_put_ino(
+ struct xfs_mount *mp,
struct xfs_dir2_sf_hdr *hdr,
struct xfs_dir2_sf_entry *sfep,
xfs_ino_t ino)
{
- xfs_dir2_sf_put_ino(hdr, xfs_dir2_sfe_inop(sfep), ino);
+ xfs_dir2_sf_put_ino(hdr, xfs_dir3_sfe_inop(mp, sfep), ino);
}
/*
@@ -141,9 +147,16 @@ xfs_dir2_block_sfsize(
int namelen; /* total name bytes */
xfs_ino_t parent = 0; /* parent inode number */
int size=0; /* total computed size */
+ int has_ftype;
mp = dp->i_mount;
+ /*
+ * if there is a filetype field, add the extra byte to the namelen
+ * for each entry that we see.
+ */
+ has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0;
+
count = i8count = namelen = 0;
btp = xfs_dir2_block_tail_p(mp, hdr);
blp = xfs_dir2_block_leaf_p(btp);
@@ -172,9 +185,10 @@ xfs_dir2_block_sfsize(
if (!isdot)
i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
#endif
+ /* take into account the file type field */
if (!isdot && !isdotdot) {
count++;
- namelen += dep->namelen;
+ namelen += dep->namelen + has_ftype;
} else if (isdotdot)
parent = be64_to_cpu(dep->inumber);
/*
@@ -300,12 +314,12 @@ xfs_dir2_block_to_sf(
(xfs_dir2_data_aoff_t)
((char *)dep - (char *)hdr));
memcpy(sfep->name, dep->name, dep->namelen);
- xfs_dir2_sfe_put_ino(sfp, sfep,
+ xfs_dir3_sfe_put_ino(mp, sfp, sfep,
be64_to_cpu(dep->inumber));
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
}
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
}
ASSERT((char *)sfep - (char *)sfp == size);
xfs_dir2_sf_check(args);
@@ -356,7 +370,7 @@ xfs_dir2_sf_addname(
/*
* Compute entry (and change in) size.
*/
- add_entsize = xfs_dir2_sf_entsize(sfp, args->namelen);
+ add_entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen);
incr_isize = add_entsize;
objchange = 0;
#if XFS_BIG_INUMS
@@ -450,8 +464,9 @@ xfs_dir2_sf_addname_easy(
/*
* Grow the in-inode space.
*/
- xfs_idata_realloc(dp, xfs_dir2_sf_entsize(sfp, args->namelen),
- XFS_DATA_FORK);
+ xfs_idata_realloc(dp,
+ xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen),
+ XFS_DATA_FORK);
/*
* Need to set up again due to realloc of the inode data.
*/
@@ -463,7 +478,7 @@ xfs_dir2_sf_addname_easy(
sfep->namelen = args->namelen;
xfs_dir2_sf_put_offset(sfep, offset);
memcpy(sfep->name, args->name, sfep->namelen);
- xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
+ xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep, args->inumber);
/*
* Update the header and inode.
*/
@@ -503,11 +518,13 @@ xfs_dir2_sf_addname_hard(
xfs_dir2_sf_hdr_t *oldsfp; /* original shortform dir */
xfs_dir2_sf_entry_t *sfep; /* entry in new dir */
xfs_dir2_sf_hdr_t *sfp; /* new shortform dir */
+ struct xfs_mount *mp;
/*
* Copy the old directory to the stack buffer.
*/
dp = args->dp;
+ mp = dp->i_mount;
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
old_isize = (int)dp->i_d.di_size;
@@ -519,13 +536,13 @@ xfs_dir2_sf_addname_hard(
* to insert the new entry.
* If it's going to end up at the end then oldsfep will point there.
*/
- for (offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount),
+ for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp),
- add_datasize = xfs_dir2_data_entsize(args->namelen),
+ add_datasize = xfs_dir3_data_entsize(mp, args->namelen),
eof = (char *)oldsfep == &buf[old_isize];
!eof;
- offset = new_offset + xfs_dir2_data_entsize(oldsfep->namelen),
- oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep),
+ offset = new_offset + xfs_dir3_data_entsize(mp, oldsfep->namelen),
+ oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep),
eof = (char *)oldsfep == &buf[old_isize]) {
new_offset = xfs_dir2_sf_get_offset(oldsfep);
if (offset + add_datasize <= new_offset)
@@ -554,7 +571,7 @@ xfs_dir2_sf_addname_hard(
sfep->namelen = args->namelen;
xfs_dir2_sf_put_offset(sfep, offset);
memcpy(sfep->name, args->name, sfep->namelen);
- xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
+ xfs_dir3_sfe_put_ino(mp, sfp, sfep, args->inumber);
sfp->count++;
#if XFS_BIG_INUMS
if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
@@ -564,7 +581,7 @@ xfs_dir2_sf_addname_hard(
* If there's more left to copy, do that.
*/
if (!eof) {
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
memcpy(sfep, oldsfep, old_isize - nbytes);
}
kmem_free(buf);
@@ -600,7 +617,7 @@ xfs_dir2_sf_addname_pick(
mp = dp->i_mount;
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
- size = xfs_dir2_data_entsize(args->namelen);
+ size = xfs_dir3_data_entsize(mp, args->namelen);
offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
sfep = xfs_dir2_sf_firstentry(sfp);
holefit = 0;
@@ -613,8 +630,8 @@ xfs_dir2_sf_addname_pick(
if (!holefit)
holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
offset = xfs_dir2_sf_get_offset(sfep) +
- xfs_dir2_data_entsize(sfep->namelen);
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ xfs_dir3_data_entsize(mp, sfep->namelen);
+ sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
}
/*
* Calculate data bytes used excluding the new entry, if this
@@ -668,31 +685,34 @@ xfs_dir2_sf_check(
int offset; /* data offset */
xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */
xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
+ struct xfs_mount *mp;
dp = args->dp;
+ mp = dp->i_mount;
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
- offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount);
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
ino = xfs_dir2_sf_get_parent_ino(sfp);
i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep)) {
ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
- ino = xfs_dir2_sfe_get_ino(sfp, sfep);
+ ino = xfs_dir3_sfe_get_ino(mp, sfp, sfep);
i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
offset =
xfs_dir2_sf_get_offset(sfep) +
- xfs_dir2_data_entsize(sfep->namelen);
+ xfs_dir3_data_entsize(mp, sfep->namelen);
+ ASSERT(xfs_dir3_sfe_get_ftype(mp, sfp, sfep) <
+ XFS_DIR3_FT_MAX);
}
ASSERT(i8count == sfp->i8count);
ASSERT(XFS_BIG_INUMS || i8count == 0);
ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
ASSERT(offset +
(sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
- (uint)sizeof(xfs_dir2_block_tail_t) <=
- dp->i_mount->m_dirblksize);
+ (uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dirblksize);
}
#endif /* DEBUG */
@@ -804,7 +824,7 @@ xfs_dir2_sf_lookup(
*/
ci_sfep = NULL;
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) {
/*
* Compare name and if it's an exact match, return the inode
* number. If it's the first case-insensitive match, store the
@@ -814,7 +834,8 @@ xfs_dir2_sf_lookup(
sfep->namelen);
if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
args->cmpresult = cmp;
- args->inumber = xfs_dir2_sfe_get_ino(sfp, sfep);
+ args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount,
+ sfp, sfep);
if (cmp == XFS_CMP_EXACT)
return XFS_ERROR(EEXIST);
ci_sfep = sfep;
@@ -870,10 +891,10 @@ xfs_dir2_sf_removename(
* Find the one we're deleting.
*/
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) {
if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
XFS_CMP_EXACT) {
- ASSERT(xfs_dir2_sfe_get_ino(sfp, sfep) ==
+ ASSERT(xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep) ==
args->inumber);
break;
}
@@ -887,7 +908,7 @@ xfs_dir2_sf_removename(
* Calculate sizes.
*/
byteoff = (int)((char *)sfep - (char *)sfp);
- entsize = xfs_dir2_sf_entsize(sfp, args->namelen);
+ entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen);
newsize = oldsize - entsize;
/*
* Copy the part if any after the removed entry, sliding it down.
@@ -1003,16 +1024,17 @@ xfs_dir2_sf_replace(
* Normal entry, look for the name.
*/
else {
- for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
- i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
+ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
+ i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) {
if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
XFS_CMP_EXACT) {
#if XFS_BIG_INUMS || defined(DEBUG)
- ino = xfs_dir2_sfe_get_ino(sfp, sfep);
+ ino = xfs_dir3_sfe_get_ino(dp->i_mount,
+ sfp, sfep);
ASSERT(args->inumber != ino);
#endif
- xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
+ xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
+ args->inumber);
break;
}
}
@@ -1120,13 +1142,13 @@ xfs_dir2_sf_toino4(
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp);
i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
- oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
+ oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
sfep->namelen = oldsfep->namelen;
sfep->offset = oldsfep->offset;
memcpy(sfep->name, oldsfep->name, sfep->namelen);
- xfs_dir2_sfe_put_ino(sfp, sfep,
- xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
+ xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
}
/*
* Clean up the inode.
@@ -1195,13 +1217,13 @@ xfs_dir2_sf_toino8(
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp);
i < sfp->count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
- oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
+ oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
sfep->namelen = oldsfep->namelen;
sfep->offset = oldsfep->offset;
memcpy(sfep->name, oldsfep->name, sfep->namelen);
- xfs_dir2_sfe_put_ino(sfp, sfep,
- xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
+ xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
}
/*
* Clean up the inode.
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 9526ec4..817142b 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -565,7 +565,10 @@ xlog_print_trans_inode_core(xfs_icdinode_t *ip)
}
void
-xlog_print_dir2_sf(xfs_dir2_sf_hdr_t *sfp, int size)
+xlog_print_dir2_sf(
+ struct xlog *log,
+ xfs_dir2_sf_hdr_t *sfp,
+ int size)
{
xfs_ino_t ino;
int count;
@@ -587,21 +590,23 @@ xlog_print_dir2_sf(xfs_dir2_sf_hdr_t *sfp, int size)
count = sfp->count;
sfep = xfs_dir2_sf_firstentry(sfp);
for (i = 0; i < count; i++) {
- ino = xfs_dir2_sfe_get_ino(sfp, sfep);
+ ino = xfs_dir3_sfe_get_ino(log->l_mp, sfp, sfep);
memmove(namebuf, (sfep->name), sfep->namelen);
namebuf[sfep->namelen] = '\0';
printf(_("%s ino 0x%llx namelen %d\n"),
namebuf, (unsigned long long)ino, sfep->namelen);
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ sfep = xfs_dir3_sf_nextentry(log->l_mp, sfp, sfep);
}
}
int
-xlog_print_trans_inode(xfs_caddr_t *ptr,
- int len,
- int *i,
- int num_ops,
- boolean_t continued)
+xlog_print_trans_inode(
+ struct xlog *log,
+ xfs_caddr_t *ptr,
+ int len,
+ int *i,
+ int num_ops,
+ boolean_t continued)
{
xfs_icdinode_t dino;
xlog_op_header_t *op_head;
@@ -695,7 +700,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
case XFS_ILOG_DDATA:
printf(_("LOCAL inode data\n"));
if (mode == S_IFDIR)
- xlog_print_dir2_sf((xfs_dir2_sf_hdr_t *)*ptr, size);
+ xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
break;
default:
ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0);
@@ -722,7 +727,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
case XFS_ILOG_ADATA:
printf(_("LOCAL attr data\n"));
if (mode == S_IFDIR)
- xlog_print_dir2_sf((xfs_dir2_sf_hdr_t *)*ptr, size);
+ xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
break;
default:
ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0);
@@ -857,14 +862,16 @@ print_lsn(xfs_caddr_t string,
int
-xlog_print_record(int fd,
- int num_ops,
- int len,
- int *read_type,
- xfs_caddr_t *partial_buf,
- xlog_rec_header_t *rhead,
- xlog_rec_ext_header_t *xhdrs,
- int bad_hdr_warn)
+xlog_print_record(
+ struct xlog *log,
+ int fd,
+ int num_ops,
+ int len,
+ int *read_type,
+ xfs_caddr_t *partial_buf,
+ xlog_rec_header_t *rhead,
+ xlog_rec_ext_header_t *xhdrs,
+ int bad_hdr_warn)
{
xfs_caddr_t buf, ptr;
int read_len, skip;
@@ -1011,7 +1018,7 @@ xlog_print_record(int fd,
break;
}
case XFS_LI_INODE: {
- skip = xlog_print_trans_inode(&ptr,
+ skip = xlog_print_trans_inode(log, &ptr,
be32_to_cpu(op_head->oh_len),
&i, num_ops, continued);
break;
@@ -1387,7 +1394,7 @@ void xfs_log_print(struct xlog *log,
break;
}
- error = xlog_print_record(fd, num_ops, len, &read_type, &partial_buf,
+ error = xlog_print_record(log, fd, num_ops, len, &read_type, &partial_buf,
hdr, xhdrs, first_hdr_found);
first_hdr_found++;
switch (error) {
@@ -1488,14 +1495,9 @@ loop:
}
partial_log_read:
- error= xlog_print_record(fd,
- num_ops,
- len,
- &read_type,
- &partial_buf,
- (xlog_rec_header_t *)hbuf,
- xhdrs,
- first_hdr_found);
+ error= xlog_print_record(log, fd, num_ops, len, &read_type,
+ &partial_buf, (xlog_rec_header_t *)hbuf,
+ xhdrs, first_hdr_found);
if (read_type != FULL_READ)
len -= read_type;
read_type = FULL_READ;
diff --git a/repair/dir2.c b/repair/dir2.c
index 2ca7fd1..2cccf1d 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -651,6 +651,7 @@ _("would correct bad hashval in interior dir block\n"
*/
void
process_sf_dir2_fixi8(
+ struct xfs_mount *mp,
struct xfs_dir2_sf_hdr *sfp,
xfs_dir2_sf_entry_t **next_sfep)
{
@@ -680,10 +681,10 @@ process_sf_dir2_fixi8(
xfs_dir2_sf_put_offset(newsfep,
xfs_dir2_sf_get_offset(oldsfep));
memmove(newsfep->name, oldsfep->name, newsfep->namelen);
- ino = xfs_dir2_sfe_get_ino(oldsfp, oldsfep);
- xfs_dir2_sfe_put_ino(newsfp, newsfep, ino);
- oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep);
- newsfep = xfs_dir2_sf_nextentry(newsfp, newsfep);
+ ino = xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep);
+ xfs_dir3_sfe_put_ino(mp, newsfp, newsfep, ino);
+ oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep);
+ newsfep = xfs_dir3_sf_nextentry(mp, newsfp, newsfep);
}
*next_sfep = newsfep;
free(oldsfp);
@@ -708,8 +709,8 @@ process_sf_dir2_fixoff(
for (i = 0; i < sfp->count; i++) {
xfs_dir2_sf_put_offset(sfep, offset);
- offset += xfs_dir2_data_entsize(sfep->namelen);
- sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+ offset += xfs_dir3_data_entsize(mp, sfep->namelen);
+ sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
}
}
@@ -771,7 +772,7 @@ process_sf_dir2(
/*
* check for bad entry count
*/
- if (num_entries * xfs_dir2_sf_entsize(sfp, 1) +
+ if (num_entries * xfs_dir3_sf_entsize(mp, sfp, 1) +
xfs_dir2_sf_hdr_size(0) > max_size || num_entries == 0)
num_entries = 0xFF;
@@ -787,7 +788,7 @@ process_sf_dir2(
sfep = next_sfep;
junkit = 0;
bad_sfnamelen = 0;
- lino = xfs_dir2_sfe_get_ino(sfp, sfep);
+ lino = xfs_dir3_sfe_get_ino(mp, sfp, sfep);
/*
* if entry points to self, junk it since only '.' or '..'
* should do that and shortform dirs don't contain either
@@ -901,7 +902,7 @@ _("zero length entry in shortform dir %" PRIu64 ""),
break;
}
} else if ((__psint_t) sfep - (__psint_t) sfp +
- xfs_dir2_sf_entsize(sfp, sfep->namelen)
+ xfs_dir3_sf_entsize(mp, sfp, sfep->namelen)
> ino_dir_size) {
bad_sfnamelen = 1;
@@ -972,7 +973,7 @@ _("entry contains offset out of order in shortform dir %" PRIu64 "\n"),
bad_offset = 1;
}
offset = xfs_dir2_sf_get_offset(sfep) +
- xfs_dir2_data_entsize(namelen);
+ xfs_dir3_data_entsize(mp, namelen);
/*
* junk the entry by copying up the rest of the
@@ -989,7 +990,7 @@ _("entry contains offset out of order in shortform dir %" PRIu64 "\n"),
name[namelen] = '\0';
if (!no_modify) {
- tmp_elen = xfs_dir2_sf_entsize(sfp,
+ tmp_elen = xfs_dir3_sf_entsize(mp, sfp,
sfep->namelen);
be64_add_cpu(&dip->di_size, -tmp_elen);
ino_dir_size -= tmp_elen;
@@ -1043,8 +1044,8 @@ _("would have junked entry \"%s\" in directory inode %" PRIu64 "\n"),
next_sfep = (tmp_sfep == NULL)
? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep
+ ((!bad_sfnamelen)
- ? xfs_dir2_sf_entsize(sfp, sfep->namelen)
- : xfs_dir2_sf_entsize(sfp, namelen)))
+ ? xfs_dir3_sf_entsize(mp, sfp, sfep->namelen)
+ : xfs_dir3_sf_entsize(mp, sfp, namelen)))
: tmp_sfep;
}
@@ -1075,7 +1076,7 @@ _("would have corrected i8 count in directory %" PRIu64 " from %d to %d\n"),
_("corrected i8 count in directory %" PRIu64 ", was %d, now %d\n"),
ino, sfp->i8count, i8);
if (i8 == 0)
- process_sf_dir2_fixi8(sfp, &next_sfep);
+ process_sf_dir2_fixi8(mp, sfp, &next_sfep);
else
sfp->i8count = i8;
*dino_dirty = 1;
@@ -1268,12 +1269,12 @@ process_dir2_data(
continue;
}
dep = (xfs_dir2_data_entry_t *)ptr;
- if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr)
+ if (ptr + xfs_dir3_data_entsize(mp, dep->namelen) > endptr)
break;
- if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) !=
+ if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) !=
(char *)dep - (char *)d)
break;
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
lastfree = 0;
}
/*
@@ -1528,7 +1529,7 @@ _("entry \"%*.*s\" in directory inode %" PRIu64 " points to self: "),
/*
* Advance to the next entry.
*/
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
}
/*
* Check the bestfree table.
diff --git a/repair/dir2.h b/repair/dir2.h
index 3d8fe8a..df68d5c 100644
--- a/repair/dir2.h
+++ b/repair/dir2.h
@@ -72,6 +72,7 @@ process_dir2(
void
process_sf_dir2_fixi8(
+ struct xfs_mount *mp,
struct xfs_dir2_sf_hdr *sfp,
xfs_dir2_sf_entry_t **next_sfep);
diff --git a/repair/phase6.c b/repair/phase6.c
index df9b92e..77d99e1 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -1500,12 +1500,12 @@ longform_dir2_entry_check_data(
/* validate data entry size */
dep = (xfs_dir2_data_entry_t *)ptr;
- if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr)
+ if (ptr + xfs_dir3_data_entsize(mp, dep->namelen) > endptr)
break;
- if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) !=
+ if (be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) !=
(char *)dep - (char *)d)
break;
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
}
/* did we find an empty or corrupt block? */
@@ -1594,7 +1594,7 @@ longform_dir2_entry_check_data(
}
addr = xfs_dir2_db_off_to_dataptr(mp, db, ptr - (char *)d);
dep = (xfs_dir2_data_entry_t *)ptr;
- ptr += xfs_dir2_data_entsize(dep->namelen);
+ ptr += xfs_dir3_data_entsize(mp, dep->namelen);
inum = be64_to_cpu(dep->inumber);
lastfree = 0;
/*
@@ -2226,7 +2226,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp,
bad_sfnamelen = 0;
tmp_sfep = NULL;
- lino = xfs_dir2_sfe_get_ino(sfp, sfep);
+ lino = xfs_dir3_sfe_get_ino(mp, sfp, sfep);
namelen = sfep->namelen;
@@ -2255,7 +2255,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp,
break;
}
} else if (no_modify && (__psint_t) sfep - (__psint_t) sfp +
- + xfs_dir2_sf_entsize(sfp, sfep->namelen)
+ + xfs_dir3_sf_entsize(mp, sfp, sfep->namelen)
> ip->i_d.di_size) {
bad_sfnamelen = 1;
@@ -2285,7 +2285,7 @@ shortform_dir2_entry_check(xfs_mount_t *mp,
if (no_modify && verify_inum(mp, lino)) {
next_sfep = (xfs_dir2_sf_entry_t *)((__psint_t)sfep +
- xfs_dir2_sf_entsize(sfp, sfep->namelen));
+ xfs_dir3_sf_entsize(mp, sfp, sfep->namelen));
continue;
}
@@ -2393,7 +2393,7 @@ do_junkit:
if (lino == orphanage_ino)
orphanage_ino = 0;
if (!no_modify) {
- tmp_elen = xfs_dir2_sf_entsize(sfp,
+ tmp_elen = xfs_dir3_sf_entsize(mp, sfp,
sfep->namelen);
tmp_sfep = (xfs_dir2_sf_entry_t *)
((__psint_t) sfep + tmp_elen);
@@ -2446,8 +2446,8 @@ do_junkit:
next_sfep = (tmp_sfep == NULL)
? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep
+ ((!bad_sfnamelen)
- ? xfs_dir2_sf_entsize(sfp, sfep->namelen)
- : xfs_dir2_sf_entsize(sfp, namelen)))
+ ? xfs_dir3_sf_entsize(mp, sfp, sfep->namelen)
+ : xfs_dir3_sf_entsize(mp, sfp, namelen)))
: tmp_sfep;
}
@@ -2458,7 +2458,7 @@ do_junkit:
} else {
if (i8 == 0) {
tmp_sfep = next_sfep;
- process_sf_dir2_fixi8(sfp, &tmp_sfep);
+ process_sf_dir2_fixi8(mp, sfp, &tmp_sfep);
bytes_deleted +=
(__psint_t)next_sfep -
(__psint_t)tmp_sfep;
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 48/49] xfs: Add write support for dirent filetype field
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (46 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 47/49] xfs: Add read-only support for dirent filetype field Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-07-19 6:45 ` [PATCH 49/49] xfsprogs: add dtype support to mkfs and db Dave Chinner
2013-07-21 6:34 ` [PATCH 00/49] xfsprogs: patches for crc-dev branch Michael L. Semon
49 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Add support to propagate and add filetype values into the on-disk
directs. This involves passing the filetype into the xfs_da_args
structure along with the name and namelength for direct operations,
and encoding it into the dirent at the same time we write the inode
number into the dirent.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/xfs_sb.h | 3 ++-
libxfs/xfs_dir2_block.c | 7 +++++++
libxfs/xfs_dir2_data.c | 2 ++
libxfs/xfs_dir2_leaf.c | 3 +++
libxfs/xfs_dir2_node.c | 3 +++
libxfs/xfs_dir2_sf.c | 35 +++++++++++++++++++++++++++--------
6 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index c5b1c04..4851137 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -594,7 +594,8 @@ xfs_sb_has_ro_compat_feature(
}
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
-#define XFS_SB_FEAT_INCOMPAT_ALL 0
+#define XFS_SB_FEAT_INCOMPAT_ALL \
+ (XFS_SB_FEAT_INCOMPAT_FTYPE)
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index 615eea9..3e4bc53 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -530,6 +530,7 @@ xfs_dir2_block_addname(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, args->namelen);
+ xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
/*
@@ -622,6 +623,7 @@ xfs_dir2_block_lookup(
* Fill in inode number, CI name if appropriate, release the block.
*/
args->inumber = be64_to_cpu(dep->inumber);
+ args->filetype = xfs_dir3_dirent_get_ftype(mp, dep);
error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
xfs_trans_brelse(args->trans, bp);
return XFS_ERROR(error);
@@ -854,6 +856,7 @@ xfs_dir2_block_replace(
* Change the inode number to the new value.
*/
dep->inumber = cpu_to_be64(args->inumber);
+ xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
xfs_dir2_data_log_entry(args->trans, bp, dep);
xfs_dir3_data_check(dp, bp);
return 0;
@@ -1140,6 +1143,7 @@ xfs_dir2_sf_to_block(
dep->inumber = cpu_to_be64(dp->i_ino);
dep->namelen = 1;
dep->name[0] = '.';
+ xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, bp, dep);
@@ -1153,6 +1157,7 @@ xfs_dir2_sf_to_block(
dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
dep->namelen = 2;
dep->name[0] = dep->name[1] = '.';
+ xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, bp, dep);
@@ -1200,6 +1205,8 @@ xfs_dir2_sf_to_block(
dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
dep->inumber = cpu_to_be64(xfs_dir3_sfe_get_ino(mp, sfp, sfep));
dep->namelen = sfep->namelen;
+ xfs_dir3_dirent_put_ftype(mp, dep,
+ xfs_dir3_sfe_get_ftype(mp, sfp, sfep));
memcpy(dep->name, sfep->name, dep->namelen);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index ea9ba91..189699f 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -133,6 +133,8 @@ __xfs_dir3_data_check(
XFS_WANT_CORRUPTED_RETURN(
be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) ==
(char *)dep - (char *)hdr);
+ XFS_WANT_CORRUPTED_RETURN(
+ xfs_dir3_dirent_get_ftype(mp, dep) < XFS_DIR3_FT_MAX);
count++;
lastfree = 0;
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index 04ad083..7ec2f19 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -878,6 +878,7 @@ xfs_dir2_leaf_addname(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
+ xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
/*
@@ -1207,6 +1208,7 @@ xfs_dir2_leaf_lookup(
* Return the found inode number & CI name if appropriate
*/
args->inumber = be64_to_cpu(dep->inumber);
+ args->filetype = xfs_dir3_dirent_get_ftype(dp->i_mount, dep);
error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
xfs_trans_brelse(tp, dbp);
xfs_trans_brelse(tp, lbp);
@@ -1537,6 +1539,7 @@ xfs_dir2_leaf_replace(
* Put the new inode number in, log it.
*/
dep->inumber = cpu_to_be64(args->inumber);
+ xfs_dir3_dirent_put_ftype(dp->i_mount, dep, args->filetype);
tp = args->trans;
xfs_dir2_data_log_entry(tp, dbp, dep);
xfs_dir3_leaf_check(dp->i_mount, lbp);
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index 5b118d5..10d1d81 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -798,6 +798,7 @@ xfs_dir2_leafn_lookup_for_entry(
xfs_trans_brelse(tp, state->extrablk.bp);
args->cmpresult = cmp;
args->inumber = be64_to_cpu(dep->inumber);
+ args->filetype = xfs_dir3_dirent_get_ftype(mp, dep);
*indexp = index;
state->extravalid = 1;
state->extrablk.bp = curbp;
@@ -1989,6 +1990,7 @@ xfs_dir2_node_addname_int(
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
+ xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
tagp = xfs_dir3_data_entry_tag_p(mp, dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dbp, dep);
@@ -2209,6 +2211,7 @@ xfs_dir2_node_replace(
* Fill in the new inode number and log the entry.
*/
dep->inumber = cpu_to_be64(inum);
+ xfs_dir3_dirent_put_ftype(state->mp, dep, args->filetype);
xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
rval = 0;
}
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index 2791d99..740cab0 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -316,6 +316,8 @@ xfs_dir2_block_to_sf(
memcpy(sfep->name, dep->name, dep->namelen);
xfs_dir3_sfe_put_ino(mp, sfp, sfep,
be64_to_cpu(dep->inumber));
+ xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+ xfs_dir3_dirent_get_ftype(mp, dep));
sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
}
@@ -479,6 +481,8 @@ xfs_dir2_sf_addname_easy(
xfs_dir2_sf_put_offset(sfep, offset);
memcpy(sfep->name, args->name, sfep->namelen);
xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep, args->inumber);
+ xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep, args->filetype);
+
/*
* Update the header and inode.
*/
@@ -572,6 +576,7 @@ xfs_dir2_sf_addname_hard(
xfs_dir2_sf_put_offset(sfep, offset);
memcpy(sfep->name, args->name, sfep->namelen);
xfs_dir3_sfe_put_ino(mp, sfp, sfep, args->inumber);
+ xfs_dir3_sfe_put_ftype(mp, sfp, sfep, args->filetype);
sfp->count++;
#if XFS_BIG_INUMS
if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
@@ -808,6 +813,7 @@ xfs_dir2_sf_lookup(
if (args->namelen == 1 && args->name[0] == '.') {
args->inumber = dp->i_ino;
args->cmpresult = XFS_CMP_EXACT;
+ args->filetype = XFS_DIR3_FT_DIR;
return XFS_ERROR(EEXIST);
}
/*
@@ -817,6 +823,7 @@ xfs_dir2_sf_lookup(
args->name[0] == '.' && args->name[1] == '.') {
args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
args->cmpresult = XFS_CMP_EXACT;
+ args->filetype = XFS_DIR3_FT_DIR;
return XFS_ERROR(EEXIST);
}
/*
@@ -836,6 +843,8 @@ xfs_dir2_sf_lookup(
args->cmpresult = cmp;
args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount,
sfp, sfep);
+ args->filetype = xfs_dir3_sfe_get_ftype(dp->i_mount,
+ sfp, sfep);
if (cmp == XFS_CMP_EXACT)
return XFS_ERROR(EEXIST);
ci_sfep = sfep;
@@ -1035,6 +1044,8 @@ xfs_dir2_sf_replace(
#endif
xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
args->inumber);
+ xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep,
+ args->filetype);
break;
}
}
@@ -1101,10 +1112,12 @@ xfs_dir2_sf_toino4(
int oldsize; /* old inode size */
xfs_dir2_sf_entry_t *sfep; /* new sf entry */
xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
+ struct xfs_mount *mp;
trace_xfs_dir2_sf_toino4(args);
dp = args->dp;
+ mp = dp->i_mount;
/*
* Copy the old directory to the buffer.
@@ -1142,13 +1155,15 @@ xfs_dir2_sf_toino4(
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp);
i < sfp->count;
- i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
- oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep),
+ oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) {
sfep->namelen = oldsfep->namelen;
sfep->offset = oldsfep->offset;
memcpy(sfep->name, oldsfep->name, sfep->namelen);
- xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
- xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ino(mp, sfp, sfep,
+ xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+ xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep));
}
/*
* Clean up the inode.
@@ -1176,10 +1191,12 @@ xfs_dir2_sf_toino8(
int oldsize; /* old inode size */
xfs_dir2_sf_entry_t *sfep; /* new sf entry */
xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
+ struct xfs_mount *mp;
trace_xfs_dir2_sf_toino8(args);
dp = args->dp;
+ mp = dp->i_mount;
/*
* Copy the old directory to the buffer.
@@ -1217,13 +1234,15 @@ xfs_dir2_sf_toino8(
for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp);
i < sfp->count;
- i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
- oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
+ i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep),
+ oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) {
sfep->namelen = oldsfep->namelen;
sfep->offset = oldsfep->offset;
memcpy(sfep->name, oldsfep->name, sfep->namelen);
- xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
- xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ino(mp, sfp, sfep,
+ xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep));
+ xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+ xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep));
}
/*
* Clean up the inode.
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* [PATCH 49/49] xfsprogs: add dtype support to mkfs and db
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (47 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 48/49] xfs: Add write " Dave Chinner
@ 2013-07-19 6:45 ` Dave Chinner
2013-07-21 6:34 ` [PATCH 00/49] xfsprogs: patches for crc-dev branch Michael L. Semon
49 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-19 6:45 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Now that we have an extra field in the dirent, add support into
xfs_db to be able to view it when looking at directory structures.
Add support to mkfs to create filesystems with filetype - we'll
always set it on CRC enabled filesystems so all new v5 filesystems
will have this functionality enabled.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
db/dir2.c | 41 ++++++++++++++++++++++++++++++++++++++++-
db/dir2.h | 1 +
db/dir2sf.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
db/dir2sf.h | 3 +++
db/field.c | 7 +++++++
db/field.h | 3 +++
db/inode.c | 23 +++++++++++++++++++++--
mkfs/xfs_mkfs.c | 7 +++++++
8 files changed, 133 insertions(+), 4 deletions(-)
diff --git a/db/dir2.c b/db/dir2.c
index 39042b3..53fe961 100644
--- a/db/dir2.c
+++ b/db/dir2.c
@@ -596,6 +596,25 @@ dir2_data_union_size(
}
}
+static int
+dir3_data_union_ftype_offset(
+ void *obj,
+ int startoff,
+ int idx)
+{
+ xfs_dir2_data_entry_t *dep;
+ xfs_dir2_data_unused_t *dup;
+
+ ASSERT(bitoffs(startoff) == 0);
+ ASSERT(idx == 0);
+ dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
+ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG)
+ return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) -
+ (char *)dup));
+ dep = (xfs_dir2_data_entry_t *)dup;
+ return bitize((int)((char *)&dep->name[dep->namelen] - (char *)dep));
+}
+
/*
* Free block functions
*/
@@ -859,7 +878,7 @@ const field_t dir3_flds[] = {
dir3_block_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
{ "dhdr", FLDT_DIR3_DATA_HDR, OI(D3OFF(hdr)), dir3_data_hdr_count,
FLD_COUNT, TYP_NONE },
- { "du", FLDT_DIR2_DATA_UNION, dir2_data_u_offset, dir2_data_u_count,
+ { "du", FLDT_DIR3_DATA_UNION, dir2_data_u_offset, dir2_data_u_count,
FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
{ "lhdr", FLDT_DIR3_LEAF_HDR, OI(L3OFF(hdr)), dir3_leaf_hdr_count,
FLD_COUNT, TYP_NONE },
@@ -880,6 +899,26 @@ const field_t dir3_flds[] = {
{ NULL }
};
+#define D3EOFF(f) bitize(offsetof(xfs_dir2_data_entry_t, f))
+#define D3UOFF(f) bitize(offsetof(xfs_dir2_data_unused_t, f))
+const field_t dir3_data_union_flds[] = {
+ { "freetag", FLDT_UINT16X, OI(D3UOFF(freetag)),
+ dir2_data_union_freetag_count, FLD_COUNT, TYP_NONE },
+ { "inumber", FLDT_INO, OI(D3EOFF(inumber)),
+ dir2_data_union_inumber_count, FLD_COUNT, TYP_INODE },
+ { "length", FLDT_DIR2_DATA_OFF, OI(D3UOFF(length)),
+ dir2_data_union_length_count, FLD_COUNT, TYP_NONE },
+ { "namelen", FLDT_UINT8D, OI(D3EOFF(namelen)),
+ dir2_data_union_namelen_count, FLD_COUNT, TYP_NONE },
+ { "name", FLDT_CHARNS, OI(D3EOFF(name)), dir2_data_union_name_count,
+ FLD_COUNT, TYP_NONE },
+ { "filetype", FLDT_UINT8D, dir3_data_union_ftype_offset, C1,
+ FLD_OFFSET, TYP_NONE },
+ { "tag", FLDT_DIR2_DATA_OFF, dir2_data_union_tag_offset,
+ dir2_data_union_tag_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
+ { NULL }
+};
+
#define DBH3OFF(f) bitize(offsetof(struct xfs_dir3_blk_hdr, f))
const field_t dir3_blkhdr_flds[] = {
{ "magic", FLDT_UINT32X, OI(DBH3OFF(magic)), C1, 0, TYP_NONE },
diff --git a/db/dir2.h b/db/dir2.h
index d9dc27b..b3651d5 100644
--- a/db/dir2.h
+++ b/db/dir2.h
@@ -48,6 +48,7 @@ extern const field_t dir3_blkhdr_flds[];
extern const field_t dir3_data_hdr_flds[];
extern const field_t dir3_free_hdr_flds[];
extern const field_t dir3_leaf_hdr_flds[];
+extern const field_t dir3_data_union_flds[];
extern const field_t da3_blkinfo_flds[];
extern const field_t da3_node_hdr_flds[];
diff --git a/db/dir2sf.c b/db/dir2sf.c
index d628641..5285647 100644
--- a/db/dir2sf.c
+++ b/db/dir2sf.c
@@ -127,7 +127,6 @@ dir2_sf_entry_name_count(
return e->namelen;
}
-/*ARGSUSED*/
static int
dir2_sf_entry_inumber_offset(
void *obj,
@@ -142,6 +141,35 @@ dir2_sf_entry_inumber_offset(
return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e));
}
+static int
+dir3_sf_entry_inumber_offset(
+ void *obj,
+ int startoff,
+ int idx)
+{
+ xfs_dir2_sf_entry_t *e;
+
+ ASSERT(bitoffs(startoff) == 0);
+ ASSERT(idx == 0);
+ e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
+ /* plus 1 to skip the ftype entry */
+ return bitize((int)((char *)xfs_dir2_sf_inumberp(e) + 1 - (char *)e));
+}
+
+static int
+dir3_sf_entry_ftype_offset(
+ void *obj,
+ int startoff,
+ int idx)
+{
+ xfs_dir2_sf_entry_t *e;
+
+ ASSERT(bitoffs(startoff) == 0);
+ ASSERT(idx == 0);
+ e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
+ return bitize((int)((char *)&e->name[e->namelen] - (char *)e));
+}
+
int
dir2_sf_entry_size(
void *obj,
@@ -224,3 +252,25 @@ dir2sf_size(
e = xfs_dir3_sf_nextentry(mp, sf, e);
return bitize((int)((char *)e - (char *)sf));
}
+
+#define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f))
+const field_t dir3sf_flds[] = {
+ { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE },
+ { "list", FLDT_DIR3_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count,
+ FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE },
+ { NULL }
+};
+
+#define E3OFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f))
+const field_t dir3_sf_entry_flds[] = {
+ { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE },
+ { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE },
+ { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count,
+ FLD_COUNT, TYP_NONE },
+ { "inumber", FLDT_DIR2_INOU, dir3_sf_entry_inumber_offset, C1,
+ FLD_OFFSET, TYP_NONE },
+ { "filetype", FLDT_UINT8D, dir3_sf_entry_ftype_offset, C1,
+ FLD_OFFSET, TYP_NONE },
+ { NULL }
+};
+
diff --git a/db/dir2sf.h b/db/dir2sf.h
index 66d229c..cabe5b4 100644
--- a/db/dir2sf.h
+++ b/db/dir2sf.h
@@ -21,6 +21,9 @@ extern const field_t dir2_inou_flds[];
extern const field_t dir2_sf_hdr_flds[];
extern const field_t dir2_sf_entry_flds[];
+extern const field_t dir3sf_flds[];
+extern const field_t dir3_sf_entry_flds[];
+
extern int dir2sf_size(void *obj, int startoff, int idx);
extern int dir2_inou_size(void *obj, int startoff, int idx);
extern int dir2_sf_entry_size(void *obj, int startoff, int idx);
diff --git a/db/field.c b/db/field.c
index e4f6c7d..c6d7404 100644
--- a/db/field.c
+++ b/db/field.c
@@ -235,6 +235,13 @@ const ftattr_t ftattrtab[] = {
SI(bitsz(struct xfs_dir3_free_hdr)), 0, NULL, dir3_free_hdr_flds },
{ FLDT_DIR3_LEAF_HDR, "dir3_leaf_hdr", NULL, (char *)dir3_leaf_hdr_flds,
SI(bitsz(struct xfs_dir3_leaf_hdr)), 0, NULL, dir3_leaf_hdr_flds },
+ { FLDT_DIR3_DATA_UNION, "dir3_data_union", NULL,
+ (char *)dir3_data_union_flds, dir2_data_union_size, FTARG_SIZE, NULL,
+ dir3_data_union_flds },
+ { FLDT_DIR3_SF_ENTRY, "dir3_sf_entry", NULL, (char *)dir3_sf_entry_flds,
+ dir2_sf_entry_size, FTARG_SIZE, NULL, dir3_sf_entry_flds },
+ { FLDT_DIR3SF, "dir3sf", NULL, (char *)dir3sf_flds, dir2sf_size,
+ FTARG_SIZE, NULL, dir3sf_flds },
/* dir v2/3 node fields */
{ FLDT_DA_BLKINFO, "dir_blkinfo", NULL, (char *)da_blkinfo_flds,
diff --git a/db/field.h b/db/field.h
index b97d917..aecdf9f 100644
--- a/db/field.h
+++ b/db/field.h
@@ -116,6 +116,9 @@ typedef enum fldt {
FLDT_DIR3_DATA_HDR,
FLDT_DIR3_FREE_HDR,
FLDT_DIR3_LEAF_HDR,
+ FLDT_DIR3_DATA_UNION,
+ FLDT_DIR3_SF_ENTRY,
+ FLDT_DIR3SF,
/* dir v2/3 node fields */
FLDT_DA_BLKINFO,
diff --git a/db/inode.c b/db/inode.c
index 68ef564..7038c18 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -47,6 +47,7 @@ static int inode_u_c_count(void *obj, int startoff);
static int inode_u_dev_count(void *obj, int startoff);
static int inode_u_muuid_count(void *obj, int startoff);
static int inode_u_sfdir2_count(void *obj, int startoff);
+static int inode_u_sfdir3_count(void *obj, int startoff);
static int inode_u_symlink_count(void *obj, int startoff);
static const cmdinfo_t inode_cmd =
@@ -78,7 +79,7 @@ const field_t inode_crc_flds[] = {
{ "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0,
TYP_INODE },
{ "v3", FLDT_DINODE_V3, OI(OFF(magic)), C1, 0, TYP_NONE },
- { "u", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE },
+ { "u3", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE },
{ "a", FLDT_DINODE_A, inode_a_offset, inode_a_count,
FLD_COUNT|FLD_OFFSET, TYP_NONE },
{ NULL }
@@ -193,6 +194,7 @@ const field_t inode_u_flds[] = {
{ "dev", FLDT_DEV, NULL, inode_u_dev_count, FLD_COUNT, TYP_NONE },
{ "muuid", FLDT_UUID, NULL, inode_u_muuid_count, FLD_COUNT, TYP_NONE },
{ "sfdir2", FLDT_DIR2SF, NULL, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE },
+ { "sfdir3", FLDT_DIR3SF, NULL, inode_u_sfdir3_count, FLD_COUNT, TYP_NONE },
{ "symlink", FLDT_CHARNS, NULL, inode_u_symlink_count, FLD_COUNT,
TYP_NONE },
{ NULL }
@@ -556,7 +558,24 @@ inode_u_sfdir2_count(
ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
return dip->di_format == XFS_DINODE_FMT_LOCAL &&
(be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR &&
- xfs_sb_version_hasdirv2(&mp->m_sb);
+ xfs_sb_version_hasdirv2(&mp->m_sb) &&
+ !xfs_sb_version_hasftype(&mp->m_sb);
+}
+
+static int
+inode_u_sfdir3_count(
+ void *obj,
+ int startoff)
+{
+ xfs_dinode_t *dip;
+
+ ASSERT(bitoffs(startoff) == 0);
+ ASSERT(obj == iocur_top->data);
+ dip = obj;
+ ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
+ return dip->di_format == XFS_DINODE_FMT_LOCAL &&
+ (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR &&
+ xfs_sb_version_hasftype(&mp->m_sb);
}
int
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 62e4d27..2a172cc 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2513,6 +2513,13 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
lsectorsize != BBSIZE),
nci, sbp->sb_features2 != 0);
/*
+ * dirent filetype field always enabled on v5 superblocks
+ */
+ if (crcs_enabled) {
+ sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
+ }
+
+ /*
* Due to a structure alignment issue, sb_features2 ended up in one
* of two locations, the second "incorrect" location represented by
* the sb_bad_features2 field. To avoid older kernels mounting
--
1.8.3.2
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
` (48 preceding siblings ...)
2013-07-19 6:45 ` [PATCH 49/49] xfsprogs: add dtype support to mkfs and db Dave Chinner
@ 2013-07-21 6:34 ` Michael L. Semon
2013-07-22 23:32 ` Dave Chinner
49 siblings, 1 reply; 107+ messages in thread
From: Michael L. Semon @ 2013-07-21 6:34 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/2013 02:44 AM, Dave Chinner wrote:
> Comments, thoughts, flames?
I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
kernel, but the xfstests look like a disaster by going that way.
The combination of 3.12 XFS code and 3.12 xfsprogs seems to be
working well. xfs_repair, mkfs.xfs, and xfs_logprint still seem
to work either way.
The following patches had issues during the `git am` session:
# Patch 11
Applying: libxfs: sync xfs_ialloc.c to the kernel code
/usr/src/xfs/xfsprogs/.git/rebase-apply/patch:226: trailing whitespace.
/*
warning: 1 line adds whitespace errors.
# Patch 20
Applying: xfs: separate dquot on disk format definitions out of xfs_quota.h
/usr/src/xfs/xfsprogs/.git/rebase-apply/patch:64: trailing whitespace.
* This header file defines all the on-disk format definitions for
warning: 1 line adds whitespace errors.
# Patch 27
Applying: xfs: move inode fork definitions to a new header file
fatal: corrupt patch at line 2313
Patch failed at 0001 xfs: move inode fork definitions to a new header file
The copy of the patch that failed is found in:
/usr/src/xfs/xfsprogs/.git/rebase-apply/patch
When you have resolved this problem, run "git am --resolved".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
# Deleted the blank line from the patch (Thunderbird save error?).
# Patch 27 (Take 2)
Applying: xfs: move inode fork definitions to a new header file
# Patch 49
Applying: xfsprogs: add dtype support to mkfs and db
/usr/src/xfs/xfsprogs/.git/rebase-apply/patch:163: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
In other words, everything works so far. Again, on one PC, the xfstests
results are awful, with many xfs/* tests failing. The results have yet
to be reviwed closely, though. There's a chance that something in
xfstests didn't build against xfsprogs...unless all the hole punch and
dmapi tests really are having issues...not enough info yet...
Thanks!
Michael
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-21 6:34 ` [PATCH 00/49] xfsprogs: patches for crc-dev branch Michael L. Semon
@ 2013-07-22 23:32 ` Dave Chinner
2013-07-23 3:36 ` Michael L. Semon
0 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-22 23:32 UTC (permalink / raw)
To: Michael L. Semon; +Cc: xfs
On Sun, Jul 21, 2013 at 02:34:03AM -0400, Michael L. Semon wrote:
> On 07/19/2013 02:44 AM, Dave Chinner wrote:
>
> > Comments, thoughts, flames?
>
> I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
> kernel, but the xfstests look like a disaster by going that way.
We'll, if you don't have all the filtering patches that I posted a
while back it'll make quite a mess with all the experimental
warnings mkfs and repair emit, and the xfs_db tests that modify
filesystem structures will all also fail...
I'll repost them later today...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-22 23:32 ` Dave Chinner
@ 2013-07-23 3:36 ` Michael L. Semon
2013-07-23 4:44 ` Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Michael L. Semon @ 2013-07-23 3:36 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/22/2013 07:32 PM, Dave Chinner wrote:
> On Sun, Jul 21, 2013 at 02:34:03AM -0400, Michael L. Semon wrote:
>> On 07/19/2013 02:44 AM, Dave Chinner wrote:
>>
>>> Comments, thoughts, flames?
>>
>> I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
>> kernel, but the xfstests look like a disaster by going that way.
>
> We'll, if you don't have all the filtering patches that I posted a
> while back it'll make quite a mess with all the experimental
> warnings mkfs and repair emit, and the xfs_db tests that modify
> filesystem structures will all also fail...
I've been slacking on xfstests updates. The problem may exist
between keyboard and chair, though: I was trying to copy a merged
xfsprogs from one PC to another, then build everything from `make
distclean` after deleting /usr/include/xfs. Something must have
gone wrong...won't be the first time...
> I'll repost them later today...
I'll take this patchset home and see if any of them were not
committed to the xfsprogs git:
http://oss.sgi.com/archives/xfs/2013-06/msg00217.html
Is this the correct patchset?
Thanks!
Michael
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-23 3:36 ` Michael L. Semon
@ 2013-07-23 4:44 ` Dave Chinner
2013-07-23 21:02 ` Michael L. Semon
0 siblings, 1 reply; 107+ messages in thread
From: Dave Chinner @ 2013-07-23 4:44 UTC (permalink / raw)
To: Michael L. Semon; +Cc: xfs
On Mon, Jul 22, 2013 at 11:36:58PM -0400, Michael L. Semon wrote:
> On 07/22/2013 07:32 PM, Dave Chinner wrote:
> > On Sun, Jul 21, 2013 at 02:34:03AM -0400, Michael L. Semon wrote:
> >> On 07/19/2013 02:44 AM, Dave Chinner wrote:
> >>
> >>> Comments, thoughts, flames?
> >>
> >> I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
> >> kernel, but the xfstests look like a disaster by going that way.
> >
> > We'll, if you don't have all the filtering patches that I posted a
> > while back it'll make quite a mess with all the experimental
> > warnings mkfs and repair emit, and the xfs_db tests that modify
> > filesystem structures will all also fail...
>
> I've been slacking on xfstests updates. The problem may exist
> between keyboard and chair, though: I was trying to copy a merged
> xfsprogs from one PC to another, then build everything from `make
> distclean` after deleting /usr/include/xfs. Something must have
> gone wrong...won't be the first time...
>
> > I'll repost them later today...
>
> I'll take this patchset home and see if any of them were not
> committed to the xfsprogs git:
>
> http://oss.sgi.com/archives/xfs/2013-06/msg00217.html
>
> Is this the correct patchset?
Yeah, that's it, thugh I have a more recent version of it locally...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-23 4:44 ` Dave Chinner
@ 2013-07-23 21:02 ` Michael L. Semon
2013-07-24 3:52 ` Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Michael L. Semon @ 2013-07-23 21:02 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/23/2013 12:44 AM, Dave Chinner wrote:
> On Mon, Jul 22, 2013 at 11:36:58PM -0400, Michael L. Semon wrote:
>> On 07/22/2013 07:32 PM, Dave Chinner wrote:
>>> On Sun, Jul 21, 2013 at 02:34:03AM -0400, Michael L. Semon wrote:
>>>> On 07/19/2013 02:44 AM, Dave Chinner wrote:
>>>>
>>>>> Comments, thoughts, flames?
>>>>
>>>> I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
>>>> kernel, but the xfstests look like a disaster by going that way.
>>>
>>> We'll, if you don't have all the filtering patches that I posted a
>>> while back it'll make quite a mess with all the experimental
>>> warnings mkfs and repair emit, and the xfs_db tests that modify
>>> filesystem structures will all also fail...
>>
>> I've been slacking on xfstests updates. The problem may exist
>> between keyboard and chair, though: I was trying to copy a merged
>> xfsprogs from one PC to another, then build everything from `make
>> distclean` after deleting /usr/include/xfs. Something must have
>> gone wrong...won't be the first time...
>>
>>> I'll repost them later today...
>>
>> I'll take this patchset home and see if any of them were not
>> committed to the xfsprogs git:
>>
>> http://oss.sgi.com/archives/xfs/2013-06/msg00217.html
>>
>> Is this the correct patchset?
>
> Yeah, that's it, thugh I have a more recent version of it locally...
>
> Cheers,
>
> Dave.
Thanks. After applying this patchset and compiling dmapi, xfsprogs,
xfsdump, and xfstests around in circles several times, it looks
rather sane now. Two issues remain, one reproduced on another PC:
1) The earlier worries about dmapi and hole punching comes from the
results of xfs/145 being run. It hasn't been that long, but I've
forgotten the last time xfstests gave messages like "[not run] DMAPI
modules not loaded." dmapi is installed as a prerequisite; I have
precisely zero knowledge of what happens when it is enabled.
2) There are two PCs: the one being discussed here, and the all-3.12
setup that is in mid-bisect. For CRC filesystems made by the new
mkfs.xfs for the 3.11.0-rc and 3.10.0+ mid-bisect kernels, attempts
to mount them fail with a dmesg like this (by memory)...
XFS(sdb6): ... unknown incompatible features (0x1) detected ...
Filesystem can not be safely mounted by this kernel.
Is there an extra flag that can be passed to mkfs.xfs for the sake
of older CRC-capable kernels? FWIW, both PCs could still mount
CRC-enabled XFS filesystems made during the kernel 3.10-rc cycle.
Thanks again!
Michael
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 00/49] xfsprogs: patches for crc-dev branch
2013-07-23 21:02 ` Michael L. Semon
@ 2013-07-24 3:52 ` Dave Chinner
0 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-07-24 3:52 UTC (permalink / raw)
To: Michael L. Semon; +Cc: xfs
On Tue, Jul 23, 2013 at 05:02:25PM -0400, Michael L. Semon wrote:
> On 07/23/2013 12:44 AM, Dave Chinner wrote:
> > On Mon, Jul 22, 2013 at 11:36:58PM -0400, Michael L. Semon wrote:
> >> On 07/22/2013 07:32 PM, Dave Chinner wrote:
> >>> On Sun, Jul 21, 2013 at 02:34:03AM -0400, Michael L. Semon wrote:
> >>>> On 07/19/2013 02:44 AM, Dave Chinner wrote:
> >>>>
> >>>>> Comments, thoughts, flames?
> >>>>
> >>>> I was hoping that I could use this 3.12 patchset with a 3.11.0-rc
> >>>> kernel, but the xfstests look like a disaster by going that way.
> >>>
> >>> We'll, if you don't have all the filtering patches that I posted a
> >>> while back it'll make quite a mess with all the experimental
> >>> warnings mkfs and repair emit, and the xfs_db tests that modify
> >>> filesystem structures will all also fail...
> >>
> >> I've been slacking on xfstests updates. The problem may exist
> >> between keyboard and chair, though: I was trying to copy a merged
> >> xfsprogs from one PC to another, then build everything from `make
> >> distclean` after deleting /usr/include/xfs. Something must have
> >> gone wrong...won't be the first time...
> >>
> >>> I'll repost them later today...
> >>
> >> I'll take this patchset home and see if any of them were not
> >> committed to the xfsprogs git:
> >>
> >> http://oss.sgi.com/archives/xfs/2013-06/msg00217.html
> >>
> >> Is this the correct patchset?
> >
> > Yeah, that's it, thugh I have a more recent version of it locally...
> >
> > Cheers,
> >
> > Dave.
>
>
> Thanks. After applying this patchset and compiling dmapi, xfsprogs,
> xfsdump, and xfstests around in circles several times, it looks
> rather sane now. Two issues remain, one reproduced on another PC:
>
> 1) The earlier worries about dmapi and hole punching comes from the
> results of xfs/145 being run. It hasn't been that long, but I've
> forgotten the last time xfstests gave messages like "[not run] DMAPI
> modules not loaded." dmapi is installed as a prerequisite; I have
> precisely zero knowledge of what happens when it is enabled.
All the tests using dmapi should be detecting that your kernel does
not support dmapi and therefore should not be run....
> 2) There are two PCs: the one being discussed here, and the all-3.12
> setup that is in mid-bisect. For CRC filesystems made by the new
> mkfs.xfs for the 3.11.0-rc and 3.10.0+ mid-bisect kernels, attempts
> to mount them fail with a dmesg like this (by memory)...
>
> XFS(sdb6): ... unknown incompatible features (0x1) detected ...
> Filesystem can not be safely mounted by this kernel.
Yes, that's because the new mkfs sets the dirent filetype field
feature bit, and older kernels don't know anything about that.
> Is there an extra flag that can be passed to mkfs.xfs for the sake
> of older CRC-capable kernels?
No, I didn't add one because this is all still under the
"experimental" umbrella and still under active development hence
changes in flags and features are expected and there's no real
reason to provide options for features will always be turned on once
non-experimental releases are made.
> FWIW, both PCs could still mount
> CRC-enabled XFS filesystems made during the kernel 3.10-rc cycle.
Sure - mkfs doesn't enable this flag until patch 49 of this series.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 01/49] xfsprogs: introduce xfs_icreate.h
2013-07-19 6:44 ` [PATCH 01/49] xfsprogs: introduce xfs_icreate.h Dave Chinner
@ 2013-08-01 18:07 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-01 18:07 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Bring the new inode create item definitions across from kernel space
> for xfs_logprint to be able to parse.
>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
okay, sync with kernel commit 3ebe7d.
Reviewed-by: Mark Tinguely <tinguely.sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 02/49] xfsprogs: port inode create transaction changes
2013-07-19 6:44 ` [PATCH 02/49] xfsprogs: port inode create transaction changes Dave Chinner
@ 2013-08-01 19:01 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-01 19:01 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Bring across the relevant parts of the new inode create transaction
> sufficient to keep kernel/user code in sync and implement the
> infrastructure needed to make it work in xfsprogs.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
parts of kernel commits 28c8e41a, ddf6ad01, b8402b47?, and b8402b47.
No illusion to really verifying this patch and just signing off on it.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 03/49] xfsprogs: teach logprint about icreate transaction
2013-07-19 6:44 ` [PATCH 03/49] xfsprogs: teach logprint about icreate transaction Dave Chinner
@ 2013-08-01 21:30 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-01 21:30 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfs_logprint can print the icreate log items. good layout of information.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 04/49] libxfs: fix directory/attribute format issues
2013-07-19 6:44 ` [PATCH 04/49] libxfs: fix directory/attribute format issues Dave Chinner
@ 2013-08-02 13:10 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 13:10 UTC (permalink / raw)
To: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> directory data headers and attr leaf headers need padding for 32 bit
> systems to correctly align the data sections on 64 bit boundaries.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
kernel commit 5170711d
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly
2013-07-19 6:44 ` [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly Dave Chinner
@ 2013-08-02 13:12 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 13:12 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
kernel commit ade1335a
Review-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 06/49] libxfs: fix byte swapping on constants
2013-07-19 6:44 ` [PATCH 06/49] libxfs: fix byte swapping on constants Dave Chinner
@ 2013-08-02 13:51 ` Mark Tinguely
2013-08-12 0:03 ` ***** SUSPECTED SPAM ***** " Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 13:51 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The kernel code uses cpu_to_beXX() on constants in switch()
> statements for magic numbers in the btree code. Th ebyte swapping
> infratructure isn't hooked up to the proper byte swap macros to make
> this work, so fix it and then swap all the generic btree code over
> to match the kernel code.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
sync to include/uapi/linux/swab.h and (IMO backwards) switch/case
statements in xfs_allocbt_verify() like kernel commit ee1a47ab.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 07/49] libxfs: sync xfs_da_btree.c
2013-07-19 6:44 ` [PATCH 07/49] libxfs: sync xfs_da_btree.c Dave Chinner
@ 2013-08-02 14:22 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 14:22 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Some variables we renamed in the kernel code, and there are a few
> other minor differences. Fix them up.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
changed variable names in xfs_da3_node_unbalance().
add directory allocation NOFS per kernel commit b17cb364
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 08/49] libxfs: update xfs_alloc to current kernel version
2013-07-19 6:44 ` [PATCH 08/49] libxfs: update xfs_alloc to current kernel version Dave Chinner
@ 2013-08-02 15:11 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 15:11 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
okay, only difference is the initializing of the pagb_tree in
xfs_alloc_read_agf(). Don't use the busy extent tree in user space.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 09/49] libxfs: sync attr code with kernel
2013-07-19 6:44 ` [PATCH 09/49] libxfs: sync attr code with kernel Dave Chinner
@ 2013-08-02 16:02 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 16:02 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
> libxfs/xfs_attr.c | 6 +++---
> libxfs/xfs_attr_leaf.c | 7 +++----
> 2 files changed, 6 insertions(+), 7 deletions(-)
>
syncs the code in libxfs/xfs_attr.c and libxfs/xfs_attr_leaf.c to kernel
files with exception of the part in xfs_attr_shortform_to_leaf() that
gets updated by patch 14/49.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 10/49] libxfs: sync dir2 kernel differences
2013-07-19 6:44 ` [PATCH 10/49] libxfs: sync dir2 kernel differences Dave Chinner
@ 2013-08-02 16:25 ` Mark Tinguely
2013-08-08 22:04 ` Mark Tinguely
1 sibling, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 16:25 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
syncs the libxfs/xfs_dir2.c, libxfs/xfs_dir2_data.c,
libxfs/xfs_dir2_leaf.c, and libxfs/xfs_dir2_node.c to the Linux 3.12
series before kernel patch 31/49.
Reviewed-by: Mark Tinguely: <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code
2013-07-19 6:44 ` [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code Dave Chinner
@ 2013-08-02 18:08 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 18:08 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> include the missing xfs_difree() function. it's not used by
> userspace, but it makes no sense to have just this one arbitrary
> difference between the kernel and userspace files.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
adds xfs_difree(). Adds parts of kernel patches 83a9ba00 and 43df2ee6.
changed variable "offset_agbno" in xfs_imap() from "xfs_agblock_t to
"int" so patch 13/49 can move it back to "offset_agbno". good stuff.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 12/49] xfsprogs: define min/max once and use them everywhere.
2013-07-19 6:44 ` [PATCH 12/49] xfsprogs: define min/max once and use them everywhere Dave Chinner
@ 2013-08-02 18:42 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 18:42 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
remove private min/max and define it in include/platform_defs.h where it
is included in xfs.h and libxfs.h.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 13/49] libxfs: fix compile warnings
2013-07-19 6:44 ` [PATCH 13/49] libxfs: fix compile warnings Dave Chinner
@ 2013-08-02 21:13 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 21:13 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Some of the code shared with userspace causes compilation warnings
> from things turned off in the kernel code, such as differences in
> variable signedness. Fix those issues.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
convert a couple ASSERT converted to warn/exits, variable sign
correction, non-DEBUG unused variable, default string value.
---
Don't see the significance of the initialization of variables in
xfs_da3_split() and xfs_rtfree_range().
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write()
2013-07-19 6:44 ` [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write() Dave Chinner
@ 2013-08-02 21:42 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 21:42 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The conversion from local format to extent format requires
> interpretation of the data in the fork being converted, so it cannot
> be done in a generic way. It is up to the caller to convert the fork
> format to extent format before calling into xfs_bmapi_write() so
> format conversion can be done correctly.
>
> The code in xfs_bmapi_write() to convert the format is used
> implicitly by the attribute and directory code, but they
> specifically zero the fork size so that the conversion does not do
> any allocation or manipulation. Move this conversion into the
> shortform to leaf functions for the dir/attr code so the conversions
> are explicitly controlled by all callers.
>
> Now we can remove the conversion code in xfs_bmapi_write.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
same as kernel commit f3508bcd which I reviewed on June 27.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 15/49] libxfs: local to remote format support of remote symlinks
2013-07-19 6:44 ` [PATCH 15/49] libxfs: local to remote format support of remote symlinks Dave Chinner
@ 2013-08-02 22:22 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-02 22:22 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> This conversion was overlooked earlier on. Now that the differences
> between userspace and kernel space are getting smaller this bug is
> obvious. Fix it.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
same content for xfs_symlink_local_to_remote() as kernel commit f948dd76
and moved from xfs_bmap.c to xfs_symlink.c
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 16/49] xfs: separate out log format definitions
2013-07-19 6:44 ` [PATCH 16/49] xfs: separate out log format definitions Dave Chinner
@ 2013-08-03 15:15 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-03 15:15 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The on-disk format definitions for the log are spread randoms
> through a couple of header files. Consolidate it all in a single
> file that can be shared easily with userspace. This means that
> xfs_log.h and xfs_log_priv.h no longer need to be shared with
> userspace.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
sync the new user/kernel xfs_log_priv.h to patch 01/49 of the for Linux
3.12 kernel patch series which also means remove kernel-only headers.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 17/49] xfs: split out inode log item format definition
2013-07-19 6:44 ` [PATCH 17/49] xfs: split out inode log item format definition Dave Chinner
@ 2013-08-03 15:23 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-03 15:23 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Th elog item format definitions are shared with userspace. split the
> out of header files that contain kernel only defintions to make it
> simple to shared them.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
sync the new user/kernel xfs_inode.h and xfs_log_format.h to patch 02/49
of the for Linux 3.12 kernel patch series which also means remove
kernel-only headers.
---
Kernel commit 92f8ff73 added "i_pdquot" to the xfs_inode structure. If
you want we can refresh this patch on commit rather than rebase the series.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 18/49] xfs: split out buf log item format definitions
2013-07-19 6:44 ` [PATCH 18/49] xfs: split out buf log item format definitions Dave Chinner
@ 2013-08-04 23:37 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-04 23:37 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
sync the new user/kernel xfs_buf_log_item to 03/49 of the for Linux 3.12
kernel patch series which also means remove kernel-only in xfs_buf_item.h
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 19/49] xfs: split out inode log item format definition
2013-07-19 6:44 ` [PATCH 19/49] xfs: split out inode log item format definition Dave Chinner
@ 2013-08-04 23:41 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-04 23:41 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The EFI/EFD item format definitions are shared with userspace. Split
> the out of header files that contain kernel only defintions to make
> it simple to shared them.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
sync the shared user/kernel extent free items to xfs_log_format.h. The
kernel only extent free items remain in the header file,
xfs_extfree_item.h, which is removed from xfsprogs.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h
2013-07-19 6:44 ` [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h Dave Chinner
@ 2013-08-05 14:18 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 14:18 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The on disk format definitions of the on-disk dquot, log formats and
> quota off log formats are all intertwined with other definitions for
> quotas. Separate them out into their own header file so they can
> easily be shared with userspace.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 05/49.
quota entries moved to new xfs_format.h. quota log entries to
xfs_log_format.h and a def to xfs_types.h - all synced to kernel patch
05/49. xfs_quota.h is not synced to kernel 05/49, but in user patch
24/49 is removed.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h
2013-07-19 6:44 ` [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h Dave Chinner
@ 2013-08-05 14:27 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 14:27 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The on disk log format definitions for the icreate log item are
> intertwined with the kernel-only in-memory log item definitions.
> Separate the log format definitions out into their own header file
> so they can easily be shared with userspace.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 06/49.
move the shared xfs_icreate structure to xfs_log_format.h.
xfs_icreate_item.h is now kernel-only, remove from xfsprogs.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 22/49] xfs: split out on-disk transaction definitions
2013-07-19 6:44 ` [PATCH 22/49] xfs: split out on-disk transaction definitions Dave Chinner
@ 2013-08-05 15:22 ` Mark Tinguely
2013-08-05 15:24 ` Mark Tinguely
0 siblings, 1 reply; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 15:22 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There's a bunch of definitions in xfs_trans.h that define on-disk
> formats - transaction headers taht get written into the log, log
> item type definitions, etc. Split out everything into a separate
> file so that all which remains in xfs_trans.h are kernel only
> definitions.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
There are a couple comments that now wrap because of new indentation,
but they are fixed in a later patch.
The following entries deviates from kernel patch 07/49 in they are not
moved from xfs_trans.h - never are:
/*
* This structure is used to track log items associated with
* a transaction. It points to the log item and keeps some
* flags to track the state of the log item. It also tracks
* the amount of space needed to log the item it describes
* once we get to commit processing (see xfs_trans_commit()).
struct xfs_log_item_desc {
struct xfs_log_item *lid_item;
struct list_head lid_trans;
unsigned char lid_flags;
};
#define XFS_LID_DIRTY 0x1
/*
* Values for t_flags.
*/
#define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */
#define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */
#define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */
#define XFS_TRANS_SYNC 0x08 /* make commit synchronous */
#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */
#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
#define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer
count in superblock */
/*
* Values for call flags parameter.
*/
#define XFS_TRANS_RELEASE_LOG_RES 0x4
#define XFS_TRANS_ABORT 0x8
/*
* Field values for xfs_trans_mod_sb.
*/
#define XFS_TRANS_SB_ICOUNT 0x00000001
#define XFS_TRANS_SB_IFREE 0x00000002
#define XFS_TRANS_SB_FDBLOCKS 0x00000004
#define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008
#define XFS_TRANS_SB_FREXTENTS 0x00000010
#define XFS_TRANS_SB_RES_FREXTENTS 0x00000020
#define XFS_TRANS_SB_DBLOCKS 0x00000040
#define XFS_TRANS_SB_AGCOUNT 0x00000080
#define XFS_TRANS_SB_IMAXPCT 0x00000100
#define XFS_TRANS_SB_REXTSIZE 0x00000200
#define XFS_TRANS_SB_RBMBLOCKS 0x00000400
#define XFS_TRANS_SB_RBLOCKS 0x00000800
#define XFS_TRANS_SB_REXTENTS 0x00001000
#define XFS_TRANS_SB_REXTSLOG 0x00002000
/*
* Here we centralize the specification of XFS meta-data buffer
* reference count values. This determine how hard the buffer
* cache tries to hold onto the buffer.
*/
#define XFS_AGF_REF 4
#define XFS_AGI_REF 4
#define XFS_AGFL_REF 3
#define XFS_INO_BTREE_REF 3
#define XFS_ALLOC_BTREE_REF 2
#define XFS_BMAP_BTREE_REF 2
#define XFS_DIR_BTREE_REF 2
#define XFS_INO_REF 2
#define XFS_ATTR_BTREE_REF 1
#define XFS_DQUOT_REF 1
/*
* Flags for xfs_trans_ichgtime().
*/
#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 22/49] xfs: split out on-disk transaction definitions
2013-08-05 15:22 ` Mark Tinguely
@ 2013-08-05 15:24 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 15:24 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 08/05/13 10:22, Mark Tinguely wrote:
> On 07/19/13 01:44, Dave Chinner wrote:
>> From: Dave Chinner<dchinner@redhat.com>
>>
>> There's a bunch of definitions in xfs_trans.h that define on-disk
>> formats - transaction headers taht get written into the log, log
>> item type definitions, etc. Split out everything into a separate
>> file so that all which remains in xfs_trans.h are kernel only
>> definitions.
>>
>> Signed-off-by: Dave Chinner<dchinner@redhat.com>
>> ---
>
> There are a couple comments that now wrap because of new indentation,
> but they are fixed in a later patch.
>
my mistake they are removed, not added.
but ...
> The following entries deviates from kernel patch 07/49 in they are not
> moved from xfs_trans.h - never are:
>
>
...
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h
2013-07-19 6:44 ` [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h Dave Chinner
@ 2013-08-05 18:53 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 18:53 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There are quite a few realtime device definitions shared with
> userspace. Move them from xfs_rtalloc.h to xfs_rt_alloc_defs.h
> so we don't need to share xfs_rtalloc.h with userspace anymore.
>
> This removes the final __KERNEL__ region from the XFS kernel
> codebase. Yay!
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 08/49.
move shared items from xfs_rtalloc.h to xfs_format.h. xfs_rtalloc.h is
now kernel-only, remove from xfsprogs.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 24/49] xfs: introduce xfs_quota_defs.h
2013-07-19 6:44 ` [PATCH 24/49] xfs: introduce xfs_quota_defs.h Dave Chinner
@ 2013-08-05 19:09 ` Mark Tinguely
2013-08-12 0:24 ` ***** SUSPECTED SPAM ***** " Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 19:09 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There are a lot of quota flag definitions that are shared by user
> and kernel space. Move them all to xfs_quota_defs.h so we can
> unshare xfs_quota.h and remove the __KERNEL__ regions from it.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 09/49.
move remaining quota shared entries from xfs_quota.h to xfs_quota_defs.h
- as mentioned in patch 20, xfs_quota.h is now kernel-only and removed.
----
should shared files have a common name? - so far the ended in -format.X
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 25/49] libxfs: introduce xfs_trans_resv.c
2013-07-19 6:45 ` [PATCH 25/49] libxfs: introduce xfs_trans_resv.c Dave Chinner
@ 2013-08-05 20:16 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 20:16 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The log space reservation calculation code has been separated from
> the core transaction code in kernelspace. THi smeans we can add it
> here in preparation for removing xfs_trans.c to further reduce the
> differences between kernel and usrspace files.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 10/49.
move the transaction reservation items from xfs_trans.[ch] to new
xfs_trans_resv.[ch] with shortened structure name.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 26/49] libxfs: move transaction code to trans.c
2013-07-19 6:45 ` [PATCH 26/49] libxfs: move transaction code to trans.c Dave Chinner
@ 2013-08-05 20:51 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 20:51 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There is very little code left in xfs_trans.c. So little it is not
> worthtrying to share this file with kernel space any more. Move the
> code to libxfs/trans.c, and remove libxfs/xfs_trans.c.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 11/49.
change zone allocator/zone free to calloc/free, change function names to
libxfs_trans_XX.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 27/49] xfs: move inode fork definitions to a new header file
2013-07-19 6:45 ` [PATCH 27/49] xfs: move inode fork definitions to a new header file Dave Chinner
@ 2013-08-05 21:39 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 21:39 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The inode fork definitions are a combination of on-disk format
> definition and in-memory tracking and manipulation. They are both
> shared with userspace, so move them all into their own file so
> sharing is easy to do and track. This removes all inode fork
> related information from xfs_inode.h.
>
> Do the same for the all the C code that currently resides in
> xfs_inode.c for the same reason.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
xfsprogs equivalent of the for 3.12 kernel patch 12/49.
move remaining shared inode to new xfs_inode_fork.c/h. new function
prototypes.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h
2013-07-19 6:45 ` [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h Dave Chinner
@ 2013-08-05 21:57 ` Mark Tinguely
2013-08-12 0:30 ` ***** SUSPECTED SPAM ***** " Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Mark Tinguely @ 2013-08-05 21:57 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
> diff --git a/include/xfs_trans.h b/include/xfs_trans.h
> index e504103..37aca08 100644
> --- a/include/xfs_trans.h
> +++ b/include/xfs_trans.h
> @@ -89,6 +89,13 @@ struct xfs_log_item_desc {
> #define XFS_ATTR_BTREE_REF 1
> #define XFS_DQUOT_REF 1
>
> +/*
> + * Flags for xfs_trans_ichgtime().
> + */
> +#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
> +#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
> +#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
> +
in the kernel patch 13/49 these entries go into xfs_log_format.h
> #ifdef __KERNEL__
>
> struct xfs_buf;
> diff --git a/libxfs/xfs.h b/libxfs/xfs.h
> index 7149c09..1a01c61 100644
> --- a/libxfs/xfs.h
> +++ b/libxfs/xfs.h
> @@ -68,6 +68,9 @@ typedef __uint32_t inst_t; /* an instruction */
>
> #define IHOLD(ip) ((void) 0)
>
> +#define XFS_IGET_CREATE 0x1
> +#define XFS_IGET_UNTRUSTED 0x2
> +
> /* stop unused var warnings by assigning mp to itself */
> #define XFS_CORRUPTION_ERROR(e,l,mp,m) do { \
> (mp) = (mp); \
in the kernel patch 13/49 these entries go into xfs_icache.h
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations
2013-07-19 6:45 ` [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations Dave Chinner
@ 2013-08-06 13:25 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 13:25 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The only thing remaining in xfs_inode.[ch] are the operations that
> read, write or verify physical inodes in their underlying buffers.
> Move all this code to xfs_inode_buf.[ch] and so we can stop sharing
> xfs_inode.[ch] with userspace.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
missing commit cca9f93a in xfs_inode_buf.c
This resync series will have to be fixed and reposted. I will look at
the remaining patches and mention anything new errors if I can separate
them from the old errors.
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 32/49] xfs: create xfs_bmap_util.[ch]
2013-07-19 6:45 ` [PATCH 32/49] xfs: create xfs_bmap_util.[ch] Dave Chinner
@ 2013-08-06 15:13 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 15:13 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There is a bunch of code in xfs_bmap.c that is kernel specific and
> not shared with userspace. to minimise the difference between the
> kernel and userspace code, shift this unshared code to
> xfs_bmap_util.c, and the declarations to xfs_bmap_util.h.
>
> The biggest issue here is xfs_bmap_finish() - userspce has it's own
> definition of this function, and so we need to move it out of
> xfs_bmap.[ch]. This means several other files need to include
> xfs_bmap_util.c as well.
>
> It also introduces and interesting dance for the stack switching
> code in xfs_bmapi_allocate(). The stack switching/workqueue code is
> actually moved to xfs_bmap_util.c, so that userspace can simply use
> a #define in a header file to connect the dots without needing to
> know about the stack switch code at all.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
> include/xfs_bmap.h | 51 ------------
> libxfs/xfs.h | 34 ++++++++
> libxfs/xfs_bmap.c | 222 +++--------------------------------------------------
> 3 files changed, 43 insertions(+), 264 deletions(-)
>
> diff --git a/include/xfs_bmap.h b/include/xfs_bmap.h
> index ffa67b1..8b2fe97 100644
> --- a/include/xfs_bmap.h
> +++ b/include/xfs_bmap.h
> @@ -108,38 +108,6 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
> }
>
> /*
> - * Argument structure for xfs_bmap_alloc.
> - */
> -typedef struct xfs_bmalloca {
> - xfs_fsblock_t *firstblock; /* i/o first block allocated */
> - struct xfs_bmap_free *flist; /* bmap freelist */
> - struct xfs_trans *tp; /* transaction pointer */
> - struct xfs_inode *ip; /* incore inode pointer */
> - struct xfs_bmbt_irec prev; /* extent before the new one */
> - struct xfs_bmbt_irec got; /* extent after, or delayed */
> -
> - xfs_fileoff_t offset; /* offset in file filling in */
> - xfs_extlen_t length; /* i/o length asked/allocated */
> - xfs_fsblock_t blkno; /* starting block of new extent */
> -
> - struct xfs_btree_cur *cur; /* btree cursor */
> - xfs_extnum_t idx; /* current extent index */
> - int nallocs;/* number of extents alloc'd */
> - int logflags;/* flags for transaction logging */
> -
> - xfs_extlen_t total; /* total blocks needed for xaction */
> - xfs_extlen_t minlen; /* minimum allocation size (blocks) */
> - xfs_extlen_t minleft; /* amount must be left after alloc */
> - char eof; /* set if allocating past last extent */
> - char wasdel; /* replacing a delayed allocation */
> - char userdata;/* set if is user data */
> - char aeof; /* allocated space at eof */
> - char conv; /* overwriting unwritten extents */
> - int flags;
> - int stack_switch;
> -} xfs_bmalloca_t;
> -
> -/*
> * Flags for xfs_bmap_add_extent*.
> */
> #define BMAP_LEFT_CONTIG (1<< 0)
> @@ -202,23 +170,4 @@ int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx,
> xfs_extnum_t num);
> uint xfs_default_attroffset(struct xfs_inode *ip);
>
> -#ifdef __KERNEL__
> -/* bmap to userspace formatter - copy to user& advance pointer */
> -typedef int (*xfs_bmap_format_t)(void **, struct getbmapx *, int *);
> -
> -int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist,
> - int *committed);
> -int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv,
> - xfs_bmap_format_t formatter, void *arg);
> -int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff,
> - int whichfork, int *eof);
> -int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
> - int whichfork, int *count);
> -int xfs_bmap_punch_delalloc_range(struct xfs_inode *ip,
> - xfs_fileoff_t start_fsb, xfs_fileoff_t length);
> -
> -xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb);
> -
> -#endif /* __KERNEL__ */
> -
> #endif /* __XFS_BMAP_H__ */
> diff --git a/libxfs/xfs.h b/libxfs/xfs.h
> index 0113b50..276fc25 100644
> --- a/libxfs/xfs.h
> +++ b/libxfs/xfs.h
> @@ -51,6 +51,40 @@
> typedef __uint32_t uint_t;
> typedef __uint32_t inst_t; /* an instruction */
>
> +/*
> + * Argument structure for xfs_bmap_alloc.
> + */
> +typedef struct xfs_bmalloca {
> + xfs_fsblock_t *firstblock; /* i/o first block allocated */
> + struct xfs_bmap_free *flist; /* bmap freelist */
> + struct xfs_trans *tp; /* transaction pointer */
> + struct xfs_inode *ip; /* incore inode pointer */
> + struct xfs_bmbt_irec prev; /* extent before the new one */
> + struct xfs_bmbt_irec got; /* extent after, or delayed */
> +
> + xfs_fileoff_t offset; /* offset in file filling in */
> + xfs_extlen_t length; /* i/o length asked/allocated */
> + xfs_fsblock_t blkno; /* starting block of new extent */
> +
> + struct xfs_btree_cur *cur; /* btree cursor */
> + xfs_extnum_t idx; /* current extent index */
> + int nallocs;/* number of extents alloc'd */
> + int logflags;/* flags for transaction logging */
> +
> + xfs_extlen_t total; /* total blocks needed for xaction */
> + xfs_extlen_t minlen; /* minimum allocation size (blocks) */
> + xfs_extlen_t minleft; /* amount must be left after alloc */
> + char eof; /* set if allocating past last extent */
> + char wasdel; /* replacing a delayed allocation */
> + char userdata;/* set if is user data */
> + char aeof; /* allocated space at eof */
> + char conv; /* overwriting unwritten extents */
> + char stack_switch;
> + int flags;
> +} xfs_bmalloca_t;
> +
> +#define xfs_bmapi_allocate __xfs_bmapi_allocate
> +
> #ifndef EWRONGFS
> #define EWRONGFS EINVAL
> #endif
> diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
> index ce72b87..eeaea94 100644
> --- a/libxfs/xfs_bmap.c
> +++ b/libxfs/xfs_bmap.c
> @@ -74,19 +74,6 @@ xfs_bmap_compute_maxlevels(
> mp->m_bm_maxlevels[whichfork] = level;
> }
>
> -/*
> - * Convert the given file system block to a disk block. We have to treat it
> - * differently based on whether the file is a real time file or not, because the
> - * bmap code does.
> - */
> -xfs_daddr_t
> -xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
> -{
> - return (XFS_IS_REALTIME_INODE(ip) ? \
> - (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
> - XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
> -}
> -
> STATIC int /* error */
> xfs_bmbt_lookup_eq(
> struct xfs_btree_cur *cur,
> @@ -229,173 +216,6 @@ xfs_bmap_forkoff_reset(
> }
>
> /*
> - * Extent tree block counting routines.
> - */
> -
> -/*
> - * Count leaf blocks given a range of extent records.
> - */
> -STATIC void
> -xfs_bmap_count_leaves(
> - xfs_ifork_t *ifp,
> - xfs_extnum_t idx,
> - int numrecs,
> - int *count)
> -{
> - int b;
> -
> - for (b = 0; b< numrecs; b++) {
> - xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
> - *count += xfs_bmbt_get_blockcount(frp);
> - }
> -}
> -
> -/*
> - * Count leaf blocks given a range of extent records originally
> - * in btree format.
> - */
> -STATIC void
> -xfs_bmap_disk_count_leaves(
> - struct xfs_mount *mp,
> - struct xfs_btree_block *block,
> - int numrecs,
> - int *count)
> -{
> - int b;
> - xfs_bmbt_rec_t *frp;
> -
> - for (b = 1; b<= numrecs; b++) {
> - frp = XFS_BMBT_REC_ADDR(mp, block, b);
> - *count += xfs_bmbt_disk_get_blockcount(frp);
> - }
> -}
> -
> -/*
> - * Recursively walks each level of a btree
> - * to count total fsblocks is use.
> - */
> -STATIC int /* error */
> -xfs_bmap_count_tree(
> - xfs_mount_t *mp, /* file system mount point */
> - xfs_trans_t *tp, /* transaction pointer */
> - xfs_ifork_t *ifp, /* inode fork pointer */
> - xfs_fsblock_t blockno, /* file system block number */
> - int levelin, /* level in btree */
> - int *count) /* Count of blocks */
> -{
> - int error;
> - xfs_buf_t *bp, *nbp;
> - int level = levelin;
> - __be64 *pp;
> - xfs_fsblock_t bno = blockno;
> - xfs_fsblock_t nextbno;
> - struct xfs_btree_block *block, *nextblock;
> - int numrecs;
> -
> - error = xfs_btree_read_bufl(mp, tp, bno, 0,&bp, XFS_BMAP_BTREE_REF,
> - &xfs_bmbt_buf_ops);
> - if (error)
> - return error;
> - *count += 1;
> - block = XFS_BUF_TO_BLOCK(bp);
> -
> - if (--level) {
> - /* Not at node above leaves, count this level of nodes */
> - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
> - while (nextbno != NULLFSBLOCK) {
> - error = xfs_btree_read_bufl(mp, tp, nextbno, 0,&nbp,
> - XFS_BMAP_BTREE_REF,
> - &xfs_bmbt_buf_ops);
> - if (error)
> - return error;
> - *count += 1;
> - nextblock = XFS_BUF_TO_BLOCK(nbp);
> - nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib);
> - xfs_trans_brelse(tp, nbp);
> - }
> -
> - /* Dive to the next level */
> - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
> - bno = be64_to_cpu(*pp);
> - if (unlikely((error =
> - xfs_bmap_count_tree(mp, tp, ifp, bno, level, count))< 0)) {
> - xfs_trans_brelse(tp, bp);
> - XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
> - XFS_ERRLEVEL_LOW, mp);
> - return XFS_ERROR(EFSCORRUPTED);
> - }
> - xfs_trans_brelse(tp, bp);
> - } else {
> - /* count all level 1 nodes and their leaves */
> - for (;;) {
> - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
> - numrecs = be16_to_cpu(block->bb_numrecs);
> - xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
> - xfs_trans_brelse(tp, bp);
> - if (nextbno == NULLFSBLOCK)
> - break;
> - bno = nextbno;
> - error = xfs_btree_read_bufl(mp, tp, bno, 0,&bp,
> - XFS_BMAP_BTREE_REF,
> - &xfs_bmbt_buf_ops);
> - if (error)
> - return error;
> - *count += 1;
> - block = XFS_BUF_TO_BLOCK(bp);
> - }
> - }
> - return 0;
> -}
> -
> -/*
> - * Count fsblocks of the given fork.
> - */
> -int /* error */
> -xfs_bmap_count_blocks(
> - xfs_trans_t *tp, /* transaction pointer */
> - xfs_inode_t *ip, /* incore inode */
> - int whichfork, /* data or attr fork */
> - int *count) /* out: count of blocks */
> -{
> - struct xfs_btree_block *block; /* current btree block */
> - xfs_fsblock_t bno; /* block # of "block" */
> - xfs_ifork_t *ifp; /* fork structure */
> - int level; /* btree level, for checking */
> - xfs_mount_t *mp; /* file system mount structure */
> - __be64 *pp; /* pointer to block address */
> -
> - bno = NULLFSBLOCK;
> - mp = ip->i_mount;
> - ifp = XFS_IFORK_PTR(ip, whichfork);
> - if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
> - xfs_bmap_count_leaves(ifp, 0,
> - ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
> - count);
> - return 0;
> - }
> -
> - /*
> - * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
> - */
> - block = ifp->if_broot;
> - level = be16_to_cpu(block->bb_level);
> - ASSERT(level> 0);
> - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
> - bno = be64_to_cpu(*pp);
> - ASSERT(bno != NULLDFSBNO);
> - ASSERT(XFS_FSB_TO_AGNO(mp, bno)< mp->m_sb.sb_agcount);
> - ASSERT(XFS_FSB_TO_AGBNO(mp, bno)< mp->m_sb.sb_agblocks);
> -
> - if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)< 0)) {
> - XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
> - mp);
> - return XFS_ERROR(EFSCORRUPTED);
> - }
> -
> - return 0;
> -}
> -
> -/*
> * Debug/sanity checking code
> */
>
> @@ -803,7 +623,6 @@ xfs_bmap_del_free(
> kmem_zone_free(xfs_bmap_free_item_zone, free);
> }
>
> -
> /*
> * Free up any items left in the list.
> */
> @@ -1028,8 +847,8 @@ xfs_bmap_extents_to_btree(
> * Do all this logging at the end so that
> * the root is at the right level.
> */
> - xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
> xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
> + xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
> ASSERT(*curp == NULL);
> *curp = cur;
> *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
> @@ -1744,7 +1563,7 @@ xfs_bmap_last_before(
> return 0;
> }
>
> -STATIC int
> +int
> xfs_bmap_last_extent(
> struct xfs_trans *tp,
> struct xfs_inode *ip,
> @@ -1808,29 +1627,6 @@ xfs_bmap_isaeof(
> }
>
> /*
> - * Check if the endoff is outside the last extent. If so the caller will grow
> - * the allocation to a stripe unit boundary. All offsets are considered outside
> - * the end of file for an empty fork, so 1 is returned in *eof in that case.
> - */
> -int
> -xfs_bmap_eof(
> - struct xfs_inode *ip,
> - xfs_fileoff_t endoff,
> - int whichfork,
> - int *eof)
> -{
> - struct xfs_bmbt_irec rec;
> - int error;
> -
> - error = xfs_bmap_last_extent(NULL, ip, whichfork,&rec, eof);
> - if (error || *eof)
> - return error;
> -
> - *eof = endoff>= rec.br_startoff + rec.br_blockcount;
> - return 0;
> -}
> -
> -/*
> * Returns the file-relative block number of the first block past eof in
> * the file. This is not based on i_size, it is based on the extent records.
> * Returns 0 for local files, as they do not have extent records.
> @@ -3369,7 +3165,7 @@ done:
> /*
> * Adjust the size of the new extent based on di_extsize and rt extsize.
> */
> -STATIC int
> +int
> xfs_bmap_extsize_align(
> xfs_mount_t *mp,
> xfs_bmbt_irec_t *gotp, /* next extent pointer */
> @@ -3531,9 +3327,9 @@ xfs_bmap_extsize_align(
>
> #define XFS_ALLOC_GAP_UNITS 4
>
> -STATIC void
> +void
> xfs_bmap_adjacent(
> - xfs_bmalloca_t *ap) /* bmap alloc argument struct */
> + struct xfs_bmalloca *ap) /* bmap alloc argument struct */
> {
> xfs_fsblock_t adjust; /* adjustment to block numbers */
> xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
> @@ -3796,7 +3592,7 @@ xfs_bmap_btalloc_nullfb(
>
> STATIC int
> xfs_bmap_btalloc(
> - xfs_bmalloca_t *ap) /* bmap alloc argument struct */
> + struct xfs_bmalloca *ap) /* bmap alloc argument struct */
> {
> xfs_mount_t *mp; /* mount point structure */
> xfs_alloctype_t atype = 0; /* type for allocation routines */
> @@ -4028,7 +3824,7 @@ xfs_bmap_btalloc(
> */
> STATIC int
> xfs_bmap_alloc(
> - xfs_bmalloca_t *ap) /* bmap alloc argument struct */
> + struct xfs_bmalloca *ap) /* bmap alloc argument struct */
> {
> if (XFS_IS_REALTIME_INODE(ap->ip)&& ap->userdata)
> return xfs_bmap_rtalloc(ap);
> @@ -4416,8 +4212,8 @@ xfs_bmapi_delay(
> }
>
>
> -STATIC int
> -xfs_bmapi_allocate(
> +int
> +__xfs_bmapi_allocate(
> struct xfs_bmalloca *bma)
> {
> struct xfs_mount *mp = bma->ip->i_mount;
matches kernel patch 21/49.
__xfs_bmapi_allocate() in xfs_bmap.c has an extra rt variable in the
kernel file that is not in the user file. variable is not used adn
should be removed in the kernel too.
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 33/49] xfsprogs: sync minor kernel header differences
2013-07-19 6:45 ` [PATCH 33/49] xfsprogs: sync minor kernel header differences Dave Chinner
@ 2013-08-06 15:26 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 15:26 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There are lots of little differences between kernel and userspace
> headers noticable now that the files are largely the same. Clean up
> all the formatting, whitespace and other minor differences in the
> userspace headers.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
This patch is the user equivalent of the for Linux 3.12 kernel patch
22/49.
xfs_dir2.h kernel file has entry not in user:
extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct
xfs_inode *dp,
xfs_dablk_t bno, xfs_daddr_t mapped_bno);
xfs_inode_buf.h kernel file has entry not in user:
bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
xfs_trans.h user has several entries mentioned in previous patches.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 34/49] xfs: don't special case shared superblock mounts
2013-07-19 6:45 ` [PATCH 34/49] xfs: don't special case shared superblock mounts Dave Chinner
@ 2013-08-06 15:33 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 15:33 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Neither kernel or userspace support shared read-only mounts, so
> don't beother special casing the support check to be different
> between kernel and userspace. The same check canbe used as neither
> like it...
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
matches kernel patch 28/49.
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops
2013-07-19 6:45 ` [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops Dave Chinner
@ 2013-08-06 15:41 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 15:41 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Swapping extents is clearly an extent operaiton, and it is not
> shared with userspace. Move the code to xfs_extent_ops.[ch], and
> the userspace ioctl structure definition to xfs_fs.h where most of
> the other ioctl structure definitions are. The means xfs_dfrag.h is
> no longer needed in userspace.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
Equivalent to patch kernel patch 27/49.
It is out of sequence but the files are the same.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code
2013-07-19 6:45 ` [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code Dave Chinner
@ 2013-08-06 15:52 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 15:52 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Userspace running debug builds is relatively rare, so there's need
> to special case the allocation algorithm code coverage debug switch.
> As it is, userspace defines random numbers to 0, so invert the
> logic of the switch so it is effectively a no-op in userspace.
> This kills another couple of __KERNEL__ users.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 29/49.
This patch is same as kernel - there are differences in xfs_alloc.c from
other patches.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 37/49] xfs: remove __KERNEL__ from debug code
2013-07-19 6:45 ` [PATCH 37/49] xfs: remove __KERNEL__ from debug code Dave Chinner
@ 2013-08-06 16:07 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 16:07 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> There is no reason the remaining kernel-only debug code needs to
> remain kernel-only. Kill the __KERNEL__ part of the defines, and let
> userspace handle the debug code appropriately.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 30/49.
patches are the same, but at this point, the kernel and user
xfs_rtalloc.c files are out of sync - doesn't appear they ever become
synced.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c
2013-07-19 6:45 ` [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c Dave Chinner
@ 2013-08-06 16:12 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 16:12 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> It's actually an ifndef section, which means it is only included in
> userspace. however, it's deep within the libxfs code, so it's
> unlikely that the condition checked in userspace can actually occur
> (search an empty leaf) through the libxfs interfaces. i.e. if it can
> happen in usrspace, it can happen in the kernel, so remove it from
> userspace too....
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 31/49.
compares okay to the kernel patch.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h
2013-07-19 6:45 ` [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h Dave Chinner
@ 2013-08-06 16:16 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 16:16 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> xfs_types.h is shared with userspace, so having kernel specific
> types defined in it is problematic. Move all the kernel specific
> defines to xfs_linux.h so we can remove the __KERNEL__ guards from
> xfs_types.h
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 33/49.
patches are the same,
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 40/49] xfs: make struct xfs_perag kernel only
2013-07-19 6:45 ` [PATCH 40/49] xfs: make struct xfs_perag kernel only Dave Chinner
@ 2013-08-06 16:28 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 16:28 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> The struct xfs_perag has many kernel-only definitions in it,
> requiring a __KERNEL__ guard so userspace can use it to. Move it to
> xfs_mount.h so that it it kernel-only, and let userspace redefine
> it's own version of the structure containing only what it needs.
> This gets rid of another __KERNEL__ check in the XFS header files.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 34/49
looks okay.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items
2013-07-19 6:45 ` [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items Dave Chinner
@ 2013-08-06 18:23 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 18:23 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> Introduce a new structure xfs_trans_res to hold transaction
> reservation item info per log ticket.
>
> We also need to improve xfs_trans_resv_calc() by initializing the
> log count as well as log flags for permanent log reservation.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 35/49
plus find max log reservation for mkfs.
Looks good.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation
2013-07-19 6:45 ` [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation Dave Chinner
@ 2013-08-06 18:33 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 18:33 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> A preparation step.
>
> For now fsync_ts transaction use the pre-calculated log reservation
> size of tr_swrite.
> This patch introduce a new item tr_fsyncts to mp->m_reservations
> structure so that we can fetch the log reservation value for it
> in a same manner to others.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 36/49.
tr_fsyncts get it's own reservation function.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 43/49] xfs: Make writeid transaction use tr_writeid
2013-07-19 6:45 ` [PATCH 43/49] xfs: Make writeid transaction use tr_writeid Dave Chinner
@ 2013-08-06 18:38 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 18:38 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> tr_writeid is defined at mp->m_resv structure, however, it does not
> really being used when it should be..
>
> This patch changes it to tr_writeid to fetch the correct log
> reservation size.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 37/49.
now tr_writeid gets it's own reservation function.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface
2013-07-19 6:45 ` [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface Dave Chinner
@ 2013-08-06 19:12 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 19:12 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> With the new xfs_trans_res structure has been introduced, the log
> reservation size, log count as well as log flags are pre-initialized
> at mount time. So it's time to refine xfs_trans_reserve() interface
> to be more neat.
>
> Also, introduce a new helper M_RES() to return a pointer to the
> mp->m_resv structure to simplify the input.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 38/49
plus modifying the calls to libxfs_trans_reserve() in
xfsprogs.
Still think you should remove the M_RES(mp) define.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro
2013-07-19 6:45 ` [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro Dave Chinner
@ 2013-08-06 19:23 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 19:23 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> Get rid of all XFS_XXX_LOG_RES() macros since they are obsoleted now.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 39/49. also changes
a reservation max_attrsetm_trans_res_adjust to use the xfs_trans_res
information.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 46/49] xfs: Add xfs_log_rlimit.c
2013-07-19 6:45 ` [PATCH 46/49] xfs: Add xfs_log_rlimit.c Dave Chinner
@ 2013-08-06 20:31 ` Mark Tinguely
0 siblings, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 20:31 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Jie Liu<jeff.liu@oracle.com>
>
> Add source files for xfs_log_rlimit.c The new file is used for log
> size calculations and validation shared with userspace.
>
> [dchinner: xfs_log_calc_max_attrsetm_res() does not modify the
> tr_attrsetm reservation, just calculates the maximum. ]
>
> [dchinner: rework loop in xfs_log_get_max_trans_res() ]
>
> [dchinner: implement xfs_log_calc_unit_res() in util.c to give mkfs
> a worse case calculation of the log size needed. ]
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
user equivalent of the for Linux 3.12 kernel patch 41/49 plus
a lot of additional mkfs support.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 47/49] xfs: Add read-only support for dirent filetype field
2013-07-19 6:45 ` [PATCH 47/49] xfs: Add read-only support for dirent filetype field Dave Chinner
@ 2013-08-06 21:13 ` Mark Tinguely
2013-08-12 0:33 ` ***** SUSPECTED SPAM ***** " Dave Chinner
0 siblings, 1 reply; 107+ messages in thread
From: Mark Tinguely @ 2013-08-06 21:13 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:45, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Add support for the file type field in directory entries so that
> readdir can return the type of the inode the dirent points to to
> userspace without first having to read the inode off disk.
>
> The encoding of the type field is a single byte that is added to the
> end of the directory entry name length. For all intents and
> purposes, it appends a "hidden" byte to the name field which
> contains the type information. As the directory entry is already of
> dynamic size, helpers are already required to access and decode the
> direct entry structures.
>
> Hence the relevent extraction and iteration helpers are updated to
> understand the hidden byte. Helpers for reading and writing the
> filetype field from the directory entries are also added. Only the
> read helpers are used by this patch. It also adds all the code
> necessary to read the type information out of the dirents on disk.
>
> Further we add the superblock feature bit and helpers to indicate
> that we understand the on-disk format change. This is not a
> compatible change - existing kernels cannot read the new format
> successfully - so an incompatible feature flag is added. We don't
> yet allow filesystems to mount with this flag yet - that will be
> added once write support is added.
>
> Finally, the code to take the type from the VFS, convert it to an
> XFS on-disk type and put it into the xfs_name structures passed
> around is added, but the directory code does not use this field yet.
> That will be in the next patch.
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
Same as kernel patch (48/49) - written to support only v3 inodes. This
should support v2 and v3 inodes.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* Re: [PATCH 10/49] libxfs: sync dir2 kernel differences
2013-07-19 6:44 ` [PATCH 10/49] libxfs: sync dir2 kernel differences Dave Chinner
2013-08-02 16:25 ` Mark Tinguely
@ 2013-08-08 22:04 ` Mark Tinguely
1 sibling, 0 replies; 107+ messages in thread
From: Mark Tinguely @ 2013-08-08 22:04 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On 07/19/13 01:44, Dave Chinner wrote:
> From: Dave Chinner<dchinner@redhat.com>
>
> Signed-off-by: Dave Chinner<dchinner@redhat.com>
> ---
> diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
> index bdce1b3..222f08c 100644
> --- a/libxfs/xfs_dir2_node.c
> +++ b/libxfs/xfs_dir2_node.c
9th chunk in libxfs/xfs_dir2_node.c patch
> @@ -1795,9 +1793,9 @@ xfs_dir2_node_addname_int(
> /*
> * Look at the current free entry. Is it good enough?
> *
> - * The bests initialisation should be wher eteh bufer is read in
> + * The bests initialisation should be where the bufer is read in
> * the above branch. But gcc is too stupid to realise that bests
> - * iand the freehdr are actually initialised if they are placed
> + * and the freehdr are actually initialised if they are placed
> * there, so we have to do it here to avoid warnings. Blech.
> */
> bests = xfs_dir3_free_bests_p(mp, free);
A clean up in the xfsprogs master branch requires this to be removed.
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* ***** SUSPECTED SPAM ***** Re: [PATCH 06/49] libxfs: fix byte swapping on constants
2013-08-02 13:51 ` Mark Tinguely
@ 2013-08-12 0:03 ` Dave Chinner
0 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-08-12 0:03 UTC (permalink / raw)
To: Mark Tinguely; +Cc: xfs
On Fri, Aug 02, 2013 at 08:51:52AM -0500, Mark Tinguely wrote:
> On 07/19/13 01:44, Dave Chinner wrote:
> >From: Dave Chinner<dchinner@redhat.com>
> >
> >The kernel code uses cpu_to_beXX() on constants in switch()
> >statements for magic numbers in the btree code. Th ebyte swapping
> >infratructure isn't hooked up to the proper byte swap macros to make
> >this work, so fix it and then swap all the generic btree code over
> >to match the kernel code.
> >
> >Signed-off-by: Dave Chinner<dchinner@redhat.com>
> >---
>
> sync to include/uapi/linux/swab.h and (IMO backwards) switch/case
> statements in xfs_allocbt_verify() like kernel commit ee1a47ab.
The reason they are done that way is so that the compiler evalutes
the byte swap rather than doing it at runtime. i.e runtime only
requires a comparisons, instead of a endian swap then a
comparison. Hence we end up with smaller, faster code...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* ***** SUSPECTED SPAM ***** Re: [PATCH 24/49] xfs: introduce xfs_quota_defs.h
2013-08-05 19:09 ` Mark Tinguely
@ 2013-08-12 0:24 ` Dave Chinner
0 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-08-12 0:24 UTC (permalink / raw)
To: Mark Tinguely; +Cc: xfs
On Mon, Aug 05, 2013 at 02:09:10PM -0500, Mark Tinguely wrote:
> On 07/19/13 01:44, Dave Chinner wrote:
> >From: Dave Chinner<dchinner@redhat.com>
> >
> >There are a lot of quota flag definitions that are shared by user
> >and kernel space. Move them all to xfs_quota_defs.h so we can
> >unshare xfs_quota.h and remove the __KERNEL__ regions from it.
> >
> >Signed-off-by: Dave Chinner<dchinner@redhat.com>
> >---
>
>
> xfsprogs equivalent of the for 3.12 kernel patch 09/49.
>
> move remaining quota shared entries from xfs_quota.h to
> xfs_quota_defs.h - as mentioned in patch 20, xfs_quota.h is now
> kernel-only and removed.
> ----
>
> should shared files have a common name? - so far the ended in -format.X
No. The -format.h suffix is used specifically for on-disk format
definitions.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* ***** SUSPECTED SPAM ***** Re: [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h
2013-08-05 21:57 ` Mark Tinguely
@ 2013-08-12 0:30 ` Dave Chinner
0 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-08-12 0:30 UTC (permalink / raw)
To: Mark Tinguely; +Cc: xfs
On Mon, Aug 05, 2013 at 04:57:11PM -0500, Mark Tinguely wrote:
> On 07/19/13 01:45, Dave Chinner wrote:
> >From: Dave Chinner<dchinner@redhat.com>
> >
> >Signed-off-by: Dave Chinner<dchinner@redhat.com>
> >---
>
>
> >diff --git a/include/xfs_trans.h b/include/xfs_trans.h
> >index e504103..37aca08 100644
> >--- a/include/xfs_trans.h
> >+++ b/include/xfs_trans.h
> >@@ -89,6 +89,13 @@ struct xfs_log_item_desc {
> > #define XFS_ATTR_BTREE_REF 1
> > #define XFS_DQUOT_REF 1
> >
> >+/*
> >+ * Flags for xfs_trans_ichgtime().
> >+ */
> >+#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */
> >+#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
> >+#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
> >+
>
> in the kernel patch 13/49 these entries go into xfs_log_format.h
Right, in the updated kernel series xfs_trans.h is no longer shared
with userspace, and this patch series doesn't reflect that. it needs
updating.
> > #ifdef __KERNEL__
> >
> > struct xfs_buf;
> >diff --git a/libxfs/xfs.h b/libxfs/xfs.h
> >index 7149c09..1a01c61 100644
> >--- a/libxfs/xfs.h
> >+++ b/libxfs/xfs.h
> >@@ -68,6 +68,9 @@ typedef __uint32_t inst_t; /* an instruction */
> >
> > #define IHOLD(ip) ((void) 0)
> >
> >+#define XFS_IGET_CREATE 0x1
> >+#define XFS_IGET_UNTRUSTED 0x2
> >+
> > /* stop unused var warnings by assigning mp to itself */
> > #define XFS_CORRUPTION_ERROR(e,l,mp,m) do { \
> > (mp) = (mp); \
>
> in the kernel patch 13/49 these entries go into xfs_icache.h
Yup, they go into a kernel only header file. Userspace can define
them how they want as xfs_iget() has different requirements and a
completely different implementation in userspace.
>
> --Mark.
>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
* ***** SUSPECTED SPAM ***** Re: [PATCH 47/49] xfs: Add read-only support for dirent filetype field
2013-08-06 21:13 ` Mark Tinguely
@ 2013-08-12 0:33 ` Dave Chinner
0 siblings, 0 replies; 107+ messages in thread
From: Dave Chinner @ 2013-08-12 0:33 UTC (permalink / raw)
To: Mark Tinguely; +Cc: xfs
On Tue, Aug 06, 2013 at 04:13:58PM -0500, Mark Tinguely wrote:
> On 07/19/13 01:45, Dave Chinner wrote:
> >From: Dave Chinner<dchinner@redhat.com>
> >
> >Add support for the file type field in directory entries so that
> >readdir can return the type of the inode the dirent points to to
> >userspace without first having to read the inode off disk.
> >
> >The encoding of the type field is a single byte that is added to the
> >end of the directory entry name length. For all intents and
> >purposes, it appends a "hidden" byte to the name field which
> >contains the type information. As the directory entry is already of
> >dynamic size, helpers are already required to access and decode the
> >direct entry structures.
> >
> >Hence the relevent extraction and iteration helpers are updated to
> >understand the hidden byte. Helpers for reading and writing the
> >filetype field from the directory entries are also added. Only the
> >read helpers are used by this patch. It also adds all the code
> >necessary to read the type information out of the dirents on disk.
> >
> >Further we add the superblock feature bit and helpers to indicate
> >that we understand the on-disk format change. This is not a
> >compatible change - existing kernels cannot read the new format
> >successfully - so an incompatible feature flag is added. We don't
> >yet allow filesystems to mount with this flag yet - that will be
> >added once write support is added.
> >
> >Finally, the code to take the type from the VFS, convert it to an
> >XFS on-disk type and put it into the xfs_name structures passed
> >around is added, but the directory code does not use this field yet.
> >That will be in the next patch.
> >
> >Signed-off-by: Dave Chinner<dchinner@redhat.com>
> >---
>
> Same as kernel patch (48/49) - written to support only v3 inodes. This
> should support v2 and v3 inodes.
It's a directory entry format change - it has nothing to do with the
version of the inode.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 107+ messages in thread
end of thread, other threads:[~2013-08-12 0:34 UTC | newest]
Thread overview: 107+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-19 6:44 [PATCH 00/49] xfsprogs: patches for crc-dev branch Dave Chinner
2013-07-19 6:44 ` [PATCH 01/49] xfsprogs: introduce xfs_icreate.h Dave Chinner
2013-08-01 18:07 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 02/49] xfsprogs: port inode create transaction changes Dave Chinner
2013-08-01 19:01 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 03/49] xfsprogs: teach logprint about icreate transaction Dave Chinner
2013-08-01 21:30 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 04/49] libxfs: fix directory/attribute format issues Dave Chinner
2013-08-02 13:10 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 05/49] libxfs: ensure btree root split sets blkno correctly Dave Chinner
2013-08-02 13:12 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 06/49] libxfs: fix byte swapping on constants Dave Chinner
2013-08-02 13:51 ` Mark Tinguely
2013-08-12 0:03 ` ***** SUSPECTED SPAM ***** " Dave Chinner
2013-07-19 6:44 ` [PATCH 07/49] libxfs: sync xfs_da_btree.c Dave Chinner
2013-08-02 14:22 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 08/49] libxfs: update xfs_alloc to current kernel version Dave Chinner
2013-08-02 15:11 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 09/49] libxfs: sync attr code with kernel Dave Chinner
2013-08-02 16:02 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 10/49] libxfs: sync dir2 kernel differences Dave Chinner
2013-08-02 16:25 ` Mark Tinguely
2013-08-08 22:04 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 11/49] libxfs: sync xfs_ialloc.c to the kernel code Dave Chinner
2013-08-02 18:08 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 12/49] xfsprogs: define min/max once and use them everywhere Dave Chinner
2013-08-02 18:42 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 13/49] libxfs: fix compile warnings Dave Chinner
2013-08-02 21:13 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 14/49] xfs: remove local fork format handling from xfs_bmapi_write() Dave Chinner
2013-08-02 21:42 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 15/49] libxfs: local to remote format support of remote symlinks Dave Chinner
2013-08-02 22:22 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 16/49] xfs: separate out log format definitions Dave Chinner
2013-08-03 15:15 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 17/49] xfs: split out inode log item format definition Dave Chinner
2013-08-03 15:23 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 18/49] xfs: split out buf log item format definitions Dave Chinner
2013-08-04 23:37 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 19/49] xfs: split out inode log item format definition Dave Chinner
2013-08-04 23:41 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 20/49] xfs: separate dquot on disk format definitions out of xfs_quota.h Dave Chinner
2013-08-05 14:18 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 21/49] xfs: separate icreate log format definitions from xfs_icreate_item.h Dave Chinner
2013-08-05 14:27 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 22/49] xfs: split out on-disk transaction definitions Dave Chinner
2013-08-05 15:22 ` Mark Tinguely
2013-08-05 15:24 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 23/49] xfs: introduce xfs_rtalloc_defs.h Dave Chinner
2013-08-05 18:53 ` Mark Tinguely
2013-07-19 6:44 ` [PATCH 24/49] xfs: introduce xfs_quota_defs.h Dave Chinner
2013-08-05 19:09 ` Mark Tinguely
2013-08-12 0:24 ` ***** SUSPECTED SPAM ***** " Dave Chinner
2013-07-19 6:45 ` [PATCH 25/49] libxfs: introduce xfs_trans_resv.c Dave Chinner
2013-08-05 20:16 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 26/49] libxfs: move transaction code to trans.c Dave Chinner
2013-08-05 20:51 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 27/49] xfs: move inode fork definitions to a new header file Dave Chinner
2013-08-05 21:39 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 28/49] xfs: move unrealted definitions out of xfs_inode.h Dave Chinner
2013-08-05 21:57 ` Mark Tinguely
2013-08-12 0:30 ` ***** SUSPECTED SPAM ***** " Dave Chinner
2013-07-19 6:45 ` [PATCH 29/49] xfs: introduce xfs_inode_buf.c for inode buffer operations Dave Chinner
2013-08-06 13:25 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 30/49] xfs: split out the remote symlink handling Dave Chinner
2013-07-19 6:45 ` [PATCH 31/49] libxfs: switch over to xfs_sb.c and remove xfs_mount.c Dave Chinner
2013-07-19 6:45 ` [PATCH 32/49] xfs: create xfs_bmap_util.[ch] Dave Chinner
2013-08-06 15:13 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 33/49] xfsprogs: sync minor kernel header differences Dave Chinner
2013-08-06 15:26 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 34/49] xfs: don't special case shared superblock mounts Dave Chinner
2013-08-06 15:33 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 35/49] xfs: move swap extent code to xfs_extent_ops Dave Chinner
2013-08-06 15:41 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 36/49] xfs: kill __KERNEL__ check for debug code in allocation code Dave Chinner
2013-08-06 15:52 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 37/49] xfs: remove __KERNEL__ from debug code Dave Chinner
2013-08-06 16:07 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 38/49] xfs: remove __KERNEL__ check from xfs_dir2_leaf.c Dave Chinner
2013-08-06 16:12 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 39/49] xfs: move kernel specific type definitions to xfs.h Dave Chinner
2013-08-06 16:16 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 40/49] xfs: make struct xfs_perag kernel only Dave Chinner
2013-08-06 16:28 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 41/49] xfs: Introduce a new structure to hold transaction reservation items Dave Chinner
2013-08-06 18:23 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 42/49] xfs: Introduce tr_fsyncts to m_reservation Dave Chinner
2013-08-06 18:33 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 43/49] xfs: Make writeid transaction use tr_writeid Dave Chinner
2013-08-06 18:38 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 44/49] xfs: refactor xfs_trans_reserve() interface Dave Chinner
2013-08-06 19:12 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 45/49] xfs: Get rid of all XFS_XXX_LOG_RES() macro Dave Chinner
2013-08-06 19:23 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 46/49] xfs: Add xfs_log_rlimit.c Dave Chinner
2013-08-06 20:31 ` Mark Tinguely
2013-07-19 6:45 ` [PATCH 47/49] xfs: Add read-only support for dirent filetype field Dave Chinner
2013-08-06 21:13 ` Mark Tinguely
2013-08-12 0:33 ` ***** SUSPECTED SPAM ***** " Dave Chinner
2013-07-19 6:45 ` [PATCH 48/49] xfs: Add write " Dave Chinner
2013-07-19 6:45 ` [PATCH 49/49] xfsprogs: add dtype support to mkfs and db Dave Chinner
2013-07-21 6:34 ` [PATCH 00/49] xfsprogs: patches for crc-dev branch Michael L. Semon
2013-07-22 23:32 ` Dave Chinner
2013-07-23 3:36 ` Michael L. Semon
2013-07-23 4:44 ` Dave Chinner
2013-07-23 21:02 ` Michael L. Semon
2013-07-24 3:52 ` Dave Chinner
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.