You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'xfs-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs
Pull xfs updates from Dave Chinner: "There is nothing really major here - the only significant addition is the per-mount operation statistics infrastructure. Otherwises there's various ACL, xattr, DAX, AIO and logging fixes, and a smattering of small cleanups and fixes elsewhere. Summary: - per-mount operational statistics in sysfs - fixes for concurrent aio append write submission - various logging fixes - detection of zeroed logs and invalid log sequence numbers on v5 filesystems - memory allocation failure message improvements - a bunch of xattr/ACL fixes - fdatasync optimisation - miscellaneous other fixes and cleanups" * tag 'xfs-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: (39 commits) xfs: give all workqueues rescuer threads xfs: fix log recovery op header validation assert xfs: Fix error path in xfs_get_acl xfs: optimise away log forces on timestamp updates for fdatasync xfs: don't leak uuid table on rmmod xfs: invalidate cached acl if set via ioctl xfs: Plug memory leak in xfs_attrmulti_attr_set xfs: Validate the length of on-disk ACLs xfs: invalidate cached acl if set directly via xattr xfs: xfs_filemap_pmd_fault treats read faults as write faults xfs: add ->pfn_mkwrite support for DAX xfs: DAX does not use IO completion callbacks xfs: Don't use unwritten extents for DAX xfs: introduce BMAPI_ZERO for allocating zeroed extents xfs: fix inode size update overflow in xfs_map_direct() xfs: clear PF_NOFREEZE for xfsaild kthread xfs: fix an error code in xfs_fs_fill_super() xfs: stats are no longer dependent on CONFIG_PROC_FS xfs: simplify /proc teardown & error handling xfs: per-filesystem stats counter implementation ...
This commit is contained in:
@@ -29,6 +29,11 @@
|
||||
#include <linux/uio.h>
|
||||
#include <linux/vmstat.h>
|
||||
|
||||
/*
|
||||
* dax_clear_blocks() is called from within transaction context from XFS,
|
||||
* and hence this means the stack from this point must follow GFP_NOFS
|
||||
* semantics for all operations.
|
||||
*/
|
||||
int dax_clear_blocks(struct inode *inode, sector_t block, long size)
|
||||
{
|
||||
struct block_device *bdev = inode->i_sb->s_bdev;
|
||||
|
||||
+1
-1
@@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \
|
||||
xfs_message.o \
|
||||
xfs_mount.o \
|
||||
xfs_mru_cache.o \
|
||||
xfs_stats.o \
|
||||
xfs_super.o \
|
||||
xfs_symlink.o \
|
||||
xfs_sysfs.o \
|
||||
@@ -118,7 +119,6 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
|
||||
xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
|
||||
|
||||
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
|
||||
xfs-$(CONFIG_PROC_FS) += xfs_stats.o
|
||||
xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
|
||||
xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
|
||||
xfs-$(CONFIG_NFSD_PNFS) += xfs_pnfs.o
|
||||
|
||||
+6
-4
@@ -55,8 +55,9 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
|
||||
return ptr;
|
||||
if (!(++retries % 100))
|
||||
xfs_err(NULL,
|
||||
"possible memory allocation deadlock in %s (mode:0x%x)",
|
||||
__func__, lflags);
|
||||
"%s(%u) possible memory allocation deadlock size %u in %s (mode:0x%x)",
|
||||
current->comm, current->pid,
|
||||
(unsigned int)size, __func__, lflags);
|
||||
congestion_wait(BLK_RW_ASYNC, HZ/50);
|
||||
} while (1);
|
||||
}
|
||||
@@ -120,8 +121,9 @@ kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags)
|
||||
return ptr;
|
||||
if (!(++retries % 100))
|
||||
xfs_err(NULL,
|
||||
"possible memory allocation deadlock in %s (mode:0x%x)",
|
||||
__func__, lflags);
|
||||
"%s(%u) possible memory allocation deadlock in %s (mode:0x%x)",
|
||||
current->comm, current->pid,
|
||||
__func__, lflags);
|
||||
congestion_wait(BLK_RW_ASYNC, HZ/50);
|
||||
} while (1);
|
||||
}
|
||||
|
||||
@@ -482,7 +482,9 @@ xfs_agfl_verify(
|
||||
be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return xfs_log_check_lsn(mp,
|
||||
be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -651,8 +653,8 @@ xfs_alloc_ag_vextent(
|
||||
-((long)(args->len)));
|
||||
}
|
||||
|
||||
XFS_STATS_INC(xs_allocx);
|
||||
XFS_STATS_ADD(xs_allocb, args->len);
|
||||
XFS_STATS_INC(args->mp, xs_allocx);
|
||||
XFS_STATS_ADD(args->mp, xs_allocb, args->len);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1808,8 +1810,8 @@ xfs_free_ag_extent(
|
||||
|
||||
if (!isfl)
|
||||
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
|
||||
XFS_STATS_INC(xs_freex);
|
||||
XFS_STATS_ADD(xs_freeb, len);
|
||||
XFS_STATS_INC(mp, xs_freex);
|
||||
XFS_STATS_ADD(mp, xs_freeb, len);
|
||||
|
||||
trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright);
|
||||
|
||||
@@ -2259,9 +2261,13 @@ 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_meta_uuid))
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp,
|
||||
be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
|
||||
XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
|
||||
@@ -2503,7 +2509,7 @@ xfs_alloc_vextent(
|
||||
* Try near allocation first, then anywhere-in-ag after
|
||||
* the first a.g. fails.
|
||||
*/
|
||||
if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) &&
|
||||
if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) &&
|
||||
(mp->m_flags & XFS_MOUNT_32BITINODES)) {
|
||||
args->fsbno = XFS_AGB_TO_FSB(mp,
|
||||
((mp->m_agfrotor / rotorstep) %
|
||||
@@ -2634,6 +2640,14 @@ xfs_alloc_vextent(
|
||||
XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
|
||||
args->len);
|
||||
#endif
|
||||
|
||||
/* Zero the extent if we were asked to do so */
|
||||
if (args->userdata & XFS_ALLOC_USERDATA_ZERO) {
|
||||
error = xfs_zero_extent(args->ip, args->fsbno, args->len);
|
||||
if (error)
|
||||
goto error0;
|
||||
}
|
||||
|
||||
}
|
||||
xfs_perag_put(args->pag);
|
||||
return 0;
|
||||
|
||||
@@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg {
|
||||
struct xfs_mount *mp; /* file system mount point */
|
||||
struct xfs_buf *agbp; /* buffer for a.g. freelist header */
|
||||
struct xfs_perag *pag; /* per-ag struct for this agno */
|
||||
struct xfs_inode *ip; /* for userdata zeroing method */
|
||||
xfs_fsblock_t fsbno; /* file system block number */
|
||||
xfs_agnumber_t agno; /* allocation group number */
|
||||
xfs_agblock_t agbno; /* allocation group-relative block # */
|
||||
@@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg {
|
||||
char wasdel; /* set if allocation was prev delayed */
|
||||
char wasfromfl; /* set if allocation is from freelist */
|
||||
char isfl; /* set if is freelist blocks - !acctg */
|
||||
char userdata; /* set if this is user data */
|
||||
char userdata; /* mask defining userdata treatment */
|
||||
xfs_fsblock_t firstblock; /* io first block allocated */
|
||||
} xfs_alloc_arg_t;
|
||||
|
||||
/*
|
||||
* Defines for userdata
|
||||
*/
|
||||
#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/
|
||||
#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */
|
||||
#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/
|
||||
#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */
|
||||
#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */
|
||||
|
||||
xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp,
|
||||
struct xfs_perag *pag, xfs_extlen_t need);
|
||||
|
||||
@@ -125,7 +125,7 @@ xfs_attr_get(
|
||||
uint lock_mode;
|
||||
int error;
|
||||
|
||||
XFS_STATS_INC(xs_attr_get);
|
||||
XFS_STATS_INC(ip->i_mount, xs_attr_get);
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
|
||||
return -EIO;
|
||||
@@ -209,7 +209,7 @@ xfs_attr_set(
|
||||
int rsvd = (flags & ATTR_ROOT) != 0;
|
||||
int error, err2, committed, local;
|
||||
|
||||
XFS_STATS_INC(xs_attr_set);
|
||||
XFS_STATS_INC(mp, xs_attr_set);
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
|
||||
return -EIO;
|
||||
@@ -412,7 +412,7 @@ xfs_attr_remove(
|
||||
xfs_fsblock_t firstblock;
|
||||
int error;
|
||||
|
||||
XFS_STATS_INC(xs_attr_remove);
|
||||
XFS_STATS_INC(mp, xs_attr_remove);
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
|
||||
return -EIO;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -266,6 +267,8 @@ xfs_attr3_leaf_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (ichdr.magic != XFS_ATTR_LEAF_MAGIC)
|
||||
return false;
|
||||
|
||||
@@ -107,7 +107,7 @@ xfs_attr3_rmt_verify(
|
||||
if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt))
|
||||
return false;
|
||||
if (be32_to_cpu(rmt->rm_offset) +
|
||||
be32_to_cpu(rmt->rm_bytes) > XATTR_SIZE_MAX)
|
||||
be32_to_cpu(rmt->rm_bytes) > XFS_XATTR_SIZE_MAX)
|
||||
return false;
|
||||
if (rmt->rm_owner == 0)
|
||||
return false;
|
||||
|
||||
+49
-16
@@ -948,14 +948,16 @@ xfs_bmap_local_to_extents(
|
||||
bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
|
||||
|
||||
/*
|
||||
* Initialise the block and copy the data
|
||||
* Initialize the block, copy the data and log the remote buffer.
|
||||
*
|
||||
* Note: init_fn must set the buffer log item type correctly!
|
||||
* The callout is responsible for logging because the remote format
|
||||
* might differ from the local format and thus we don't know how much to
|
||||
* log here. Note that init_fn must also set the buffer log item type
|
||||
* correctly.
|
||||
*/
|
||||
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);
|
||||
/* account for the change in fork size */
|
||||
xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
|
||||
xfs_bmap_local_to_extents_empty(ip, whichfork);
|
||||
flags |= XFS_ILOG_CORE;
|
||||
@@ -1435,7 +1437,7 @@ xfs_bmap_search_extents(
|
||||
xfs_ifork_t *ifp; /* inode fork pointer */
|
||||
xfs_bmbt_rec_host_t *ep; /* extent record pointer */
|
||||
|
||||
XFS_STATS_INC(xs_look_exlist);
|
||||
XFS_STATS_INC(ip->i_mount, xs_look_exlist);
|
||||
ifp = XFS_IFORK_PTR(ip, fork);
|
||||
|
||||
ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
|
||||
@@ -1732,7 +1734,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
ASSERT(!bma->cur ||
|
||||
(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
XFS_STATS_INC(mp, xs_add_exlist);
|
||||
|
||||
#define LEFT r[0]
|
||||
#define RIGHT r[1]
|
||||
@@ -2286,7 +2288,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
||||
ASSERT(!isnullstartblock(new->br_startblock));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
XFS_STATS_INC(mp, xs_add_exlist);
|
||||
|
||||
#define LEFT r[0]
|
||||
#define RIGHT r[1]
|
||||
@@ -2946,7 +2948,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
ASSERT(!bma->cur ||
|
||||
!(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
XFS_STATS_INC(mp, xs_add_exlist);
|
||||
|
||||
state = 0;
|
||||
if (whichfork == XFS_ATTR_FORK)
|
||||
@@ -3800,8 +3802,13 @@ xfs_bmap_btalloc(
|
||||
args.wasdel = ap->wasdel;
|
||||
args.isfl = 0;
|
||||
args.userdata = ap->userdata;
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
|
||||
args.ip = ap->ip;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (tryagain && args.fsbno == NULLFSBLOCK) {
|
||||
/*
|
||||
* Exact allocation failed. Now try with alignment
|
||||
@@ -4036,7 +4043,7 @@ xfs_bmapi_read(
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
|
||||
XFS_STATS_INC(xs_blk_mapr);
|
||||
XFS_STATS_INC(mp, xs_blk_mapr);
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
|
||||
@@ -4221,7 +4228,7 @@ xfs_bmapi_delay(
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
|
||||
XFS_STATS_INC(xs_blk_mapw);
|
||||
XFS_STATS_INC(mp, xs_blk_mapw);
|
||||
|
||||
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
|
||||
error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
|
||||
@@ -4300,11 +4307,14 @@ xfs_bmapi_allocate(
|
||||
|
||||
/*
|
||||
* Indicate if this is the first user data in the file, or just any
|
||||
* user data.
|
||||
* user data. And if it is userdata, indicate whether it needs to
|
||||
* be initialised to zero during allocation.
|
||||
*/
|
||||
if (!(bma->flags & XFS_BMAPI_METADATA)) {
|
||||
bma->userdata = (bma->offset == 0) ?
|
||||
XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
|
||||
if (bma->flags & XFS_BMAPI_ZERO)
|
||||
bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
|
||||
}
|
||||
|
||||
bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
|
||||
@@ -4419,6 +4429,17 @@ xfs_bmapi_convert_unwritten(
|
||||
mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
|
||||
? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
|
||||
|
||||
/*
|
||||
* Before insertion into the bmbt, zero the range being converted
|
||||
* if required.
|
||||
*/
|
||||
if (flags & XFS_BMAPI_ZERO) {
|
||||
error = xfs_zero_extent(bma->ip, mval->br_startblock,
|
||||
mval->br_blockcount);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
|
||||
&bma->cur, mval, bma->firstblock, bma->flist,
|
||||
&tmp_logflags);
|
||||
@@ -4512,6 +4533,18 @@ xfs_bmapi_write(
|
||||
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
|
||||
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
||||
|
||||
/* zeroing is for currently only for data extents, not metadata */
|
||||
ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
|
||||
(XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
|
||||
/*
|
||||
* we can allocate unwritten extents or pre-zero allocated blocks,
|
||||
* but it makes no sense to do both at once. This would result in
|
||||
* zeroing the unwritten extent twice, but it still being an
|
||||
* unwritten extent....
|
||||
*/
|
||||
ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
|
||||
(XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
|
||||
|
||||
if (unlikely(XFS_TEST_ERROR(
|
||||
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
|
||||
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
|
||||
@@ -4525,7 +4558,7 @@ xfs_bmapi_write(
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
|
||||
XFS_STATS_INC(xs_blk_mapw);
|
||||
XFS_STATS_INC(mp, xs_blk_mapw);
|
||||
|
||||
if (*firstblock == NULLFSBLOCK) {
|
||||
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
|
||||
@@ -4718,12 +4751,12 @@ xfs_bmap_del_extent(
|
||||
xfs_filblks_t temp2; /* for indirect length calculations */
|
||||
int state = 0;
|
||||
|
||||
XFS_STATS_INC(xs_del_exlist);
|
||||
mp = ip->i_mount;
|
||||
XFS_STATS_INC(mp, xs_del_exlist);
|
||||
|
||||
if (whichfork == XFS_ATTR_FORK)
|
||||
state |= BMAP_ATTRFORK;
|
||||
|
||||
mp = ip->i_mount;
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
|
||||
(uint)sizeof(xfs_bmbt_rec_t)));
|
||||
@@ -5070,7 +5103,7 @@ xfs_bunmapi(
|
||||
*done = 1;
|
||||
return 0;
|
||||
}
|
||||
XFS_STATS_INC(xs_blk_unmap);
|
||||
XFS_STATS_INC(mp, xs_blk_unmap);
|
||||
isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
|
||||
start = bno;
|
||||
bno = start + len - 1;
|
||||
|
||||
@@ -52,9 +52,9 @@ struct xfs_bmalloca {
|
||||
xfs_extlen_t minleft; /* amount must be left after alloc */
|
||||
bool eof; /* set if allocating past last extent */
|
||||
bool wasdel; /* replacing a delayed allocation */
|
||||
bool userdata;/* set if is user data */
|
||||
bool aeof; /* allocated space at eof */
|
||||
bool conv; /* overwriting unwritten extents */
|
||||
char userdata;/* userdata mask */
|
||||
int flags;
|
||||
};
|
||||
|
||||
@@ -109,6 +109,14 @@ typedef struct xfs_bmap_free
|
||||
*/
|
||||
#define XFS_BMAPI_CONVERT 0x040
|
||||
|
||||
/*
|
||||
* allocate zeroed extents - this requires all newly allocated user data extents
|
||||
* to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set.
|
||||
* Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found
|
||||
* during the allocation range to zeroed written extents.
|
||||
*/
|
||||
#define XFS_BMAPI_ZERO 0x080
|
||||
|
||||
#define XFS_BMAPI_FLAGS \
|
||||
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
|
||||
{ XFS_BMAPI_METADATA, "METADATA" }, \
|
||||
@@ -116,7 +124,8 @@ typedef struct xfs_bmap_free
|
||||
{ XFS_BMAPI_PREALLOC, "PREALLOC" }, \
|
||||
{ XFS_BMAPI_IGSTATE, "IGSTATE" }, \
|
||||
{ XFS_BMAPI_CONTIG, "CONTIG" }, \
|
||||
{ XFS_BMAPI_CONVERT, "CONVERT" }
|
||||
{ XFS_BMAPI_CONVERT, "CONVERT" }, \
|
||||
{ XFS_BMAPI_ZERO, "ZERO" }
|
||||
|
||||
|
||||
static inline int xfs_bmapi_aflag(int w)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* Cursor allocation zone.
|
||||
@@ -222,7 +223,7 @@ xfs_btree_check_ptr(
|
||||
* long-form btree header.
|
||||
*
|
||||
* Prior to calculting the CRC, pull the LSN out of the buffer log item and put
|
||||
* it into the buffer so recovery knows what the last modifcation was that made
|
||||
* it into the buffer so recovery knows what the last modification was that made
|
||||
* it to disk.
|
||||
*/
|
||||
void
|
||||
@@ -243,8 +244,14 @@ bool
|
||||
xfs_btree_lblock_verify_crc(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn)))
|
||||
return false;
|
||||
return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -254,7 +261,7 @@ xfs_btree_lblock_verify_crc(
|
||||
* short-form btree header.
|
||||
*
|
||||
* Prior to calculting the CRC, pull the LSN out of the buffer log item and put
|
||||
* it into the buffer so recovery knows what the last modifcation was that made
|
||||
* it into the buffer so recovery knows what the last modification was that made
|
||||
* it to disk.
|
||||
*/
|
||||
void
|
||||
@@ -275,8 +282,14 @@ bool
|
||||
xfs_btree_sblock_verify_crc(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
|
||||
return false;
|
||||
return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+23
-16
@@ -84,31 +84,38 @@ union xfs_btree_rec {
|
||||
/*
|
||||
* Generic stats interface
|
||||
*/
|
||||
#define __XFS_BTREE_STATS_INC(type, stat) \
|
||||
XFS_STATS_INC(xs_ ## type ## _2_ ## stat)
|
||||
#define XFS_BTREE_STATS_INC(cur, stat) \
|
||||
#define __XFS_BTREE_STATS_INC(mp, type, stat) \
|
||||
XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat)
|
||||
#define XFS_BTREE_STATS_INC(cur, stat) \
|
||||
do { \
|
||||
struct xfs_mount *__mp = cur->bc_mp; \
|
||||
switch (cur->bc_btnum) { \
|
||||
case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \
|
||||
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \
|
||||
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
|
||||
case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
|
||||
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \
|
||||
case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \
|
||||
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \
|
||||
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \
|
||||
case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \
|
||||
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \
|
||||
case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __XFS_BTREE_STATS_ADD(type, stat, val) \
|
||||
XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val)
|
||||
#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \
|
||||
XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val)
|
||||
#define XFS_BTREE_STATS_ADD(cur, stat, val) \
|
||||
do { \
|
||||
struct xfs_mount *__mp = cur->bc_mp; \
|
||||
switch (cur->bc_btnum) { \
|
||||
case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \
|
||||
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
|
||||
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
|
||||
case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
|
||||
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
|
||||
case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
|
||||
case XFS_BTNUM_BNO: \
|
||||
__XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \
|
||||
case XFS_BTNUM_CNT: \
|
||||
__XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \
|
||||
case XFS_BTNUM_BMAP: \
|
||||
__XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \
|
||||
case XFS_BTNUM_INO: \
|
||||
__XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \
|
||||
case XFS_BTNUM_FINO: \
|
||||
__XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \
|
||||
case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* xfs_da_btree.c
|
||||
@@ -150,6 +151,8 @@ xfs_da3_node_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (ichdr.magic != XFS_DA_NODE_MAGIC)
|
||||
return false;
|
||||
@@ -322,6 +325,7 @@ xfs_da3_node_create(
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr));
|
||||
ichdr.magic = XFS_DA3_NODE_MAGIC;
|
||||
hdr3->info.blkno = cpu_to_be64(bp->b_bn);
|
||||
hdr3->info.owner = cpu_to_be64(args->dp->i_ino);
|
||||
|
||||
@@ -271,7 +271,7 @@ xfs_dir_createname(
|
||||
rval = xfs_dir_ino_validate(tp->t_mountp, inum);
|
||||
if (rval)
|
||||
return rval;
|
||||
XFS_STATS_INC(xs_dir_create);
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_create);
|
||||
}
|
||||
|
||||
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
||||
@@ -365,7 +365,7 @@ xfs_dir_lookup(
|
||||
int lock_mode;
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
XFS_STATS_INC(xs_dir_lookup);
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
|
||||
|
||||
/*
|
||||
* We need to use KM_NOFS here so that lockdep will not throw false
|
||||
@@ -444,7 +444,7 @@ xfs_dir_removename(
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT(S_ISDIR(dp->i_d.di_mode));
|
||||
XFS_STATS_INC(xs_dir_remove);
|
||||
XFS_STATS_INC(dp->i_mount, xs_dir_remove);
|
||||
|
||||
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
||||
if (!args)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* Local function prototypes.
|
||||
@@ -71,6 +72,8 @@ xfs_dir3_block_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
|
||||
return false;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* Check the consistency of the data block.
|
||||
@@ -224,6 +225,8 @@ xfs_dir3_data_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
|
||||
return false;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* Local function declarations.
|
||||
@@ -164,6 +165,8 @@ xfs_dir3_leaf_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(leaf3->info.lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (leaf->hdr.info.magic != cpu_to_be16(magic))
|
||||
return false;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_log.h"
|
||||
|
||||
/*
|
||||
* Function declarations.
|
||||
@@ -97,6 +98,8 @@ xfs_dir3_free_verify(
|
||||
return false;
|
||||
if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
|
||||
return false;
|
||||
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
|
||||
return false;
|
||||
} else {
|
||||
if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC))
|
||||
return false;
|
||||
|
||||
@@ -59,6 +59,14 @@ struct xfs_ifork;
|
||||
#define XFS_SB_VERSION_BORGBIT 0x4000 /* ASCII only case-insens. */
|
||||
#define XFS_SB_VERSION_MOREBITSBIT 0x8000
|
||||
|
||||
/*
|
||||
* The size of a single extended attribute on disk is limited by
|
||||
* the size of index values within the attribute entries themselves.
|
||||
* These are be16 fields, so we can only support attribute data
|
||||
* sizes up to 2^16 bytes in length.
|
||||
*/
|
||||
#define XFS_XATTR_SIZE_MAX (1 << 16)
|
||||
|
||||
/*
|
||||
* Supported feature bit list is just all bits in the versionnum field because
|
||||
* we've used them all up and understand them all. Except, of course, for the
|
||||
@@ -1483,13 +1491,17 @@ struct xfs_acl {
|
||||
*/
|
||||
#define XFS_ACL_MAX_ENTRIES(mp) \
|
||||
(xfs_sb_version_hascrc(&mp->m_sb) \
|
||||
? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
|
||||
? (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
|
||||
sizeof(struct xfs_acl_entry) \
|
||||
: 25)
|
||||
|
||||
#define XFS_ACL_MAX_SIZE(mp) \
|
||||
#define XFS_ACL_SIZE(cnt) \
|
||||
(sizeof(struct xfs_acl) + \
|
||||
sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
|
||||
sizeof(struct xfs_acl_entry) * cnt)
|
||||
|
||||
#define XFS_ACL_MAX_SIZE(mp) \
|
||||
XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp)))
|
||||
|
||||
|
||||
/* On-disk XFS extended attribute names */
|
||||
#define SGI_ACL_FILE "SGI_ACL_FILE"
|
||||
|
||||
@@ -489,6 +489,16 @@ typedef struct xfs_swapext
|
||||
#define XFS_FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */
|
||||
#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */
|
||||
|
||||
/*
|
||||
* ioctl limits
|
||||
*/
|
||||
#ifdef XATTR_LIST_MAX
|
||||
# define XFS_XATTR_LIST_MAX XATTR_LIST_MAX
|
||||
#else
|
||||
# define XFS_XATTR_LIST_MAX 65536
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ioctl commands that are used by Linux filesystems
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user