projects/linux·commit 97eeb4d9

Merge tag 'xfs-5.5-merge-16' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

97eeb4d9 · Linus Torvalds <[email protected]> · 2019-12-02 14:46:22 -08:00

Pull XFS updates from Darrick Wong:
 "For this release, we changed quite a few things.

  Highlights:

   - Fixed some long tail latency problems in the block allocator

   - Removed some long deprecated (and for the past several years no-op)
     mount options and ioctls

   - Strengthened the extended attribute and directory verifiers

   - Audited and fixed all the places where we could return EFSCORRUPTED
     without logging anything

   - Refactored the old SGI space allocation ioctls to make the
     equivalent fallocate calls

   - Fixed a race between fallocate and directio

   - Fixed an integer overflow when files have more than a few
     billion(!) extents

   - Fixed a longstanding bug where quota accounting could be incorrect
     when performing unwritten extent conversion on a freshly mounted fs

   - Fixed various complaints in scrub about soft lockups and
     unresponsiveness to signals

   - De-vtable'd the directory handling code, which should make it
     faster

   - Converted to the new mount api, for better or for worse

   - Cleaned up some memory leaks

  and quite a lot of other smaller fixes and cleanups.

  A more detailed summary:

   - Fill out the build string

   - Prevent inode fork extent count overflows

   - Refactor the allocator to reduce long tail latency

   - Rework incore log locking a little to reduce spinning

   - Break up the xfs_iomap_begin functions into smaller more cohesive
     parts

   - Fix allocation alignment being dropped too early when the
     allocation request is for more blocks than an AG is large

   - Other small cleanups

   - Clean up file buftarg retrieval helpers

   - Hoist the resvsp and unresvsp ioctls to the vfs

   - Remove the undocumented biosize mount option, since it has never
     been mentioned as existing or supported on linux

   - Clean up some of the mount option printing and parsing

   - Enhance attr leaf verifier to check block structure

   - Check dirent and attr names for invalid characters before passing
     them to the vfs

   - Refactor open-coded bmbt walking

   - Fix a few places where we return EIO instead of EFSCORRUPTED after
     failing metadata sanity checks

   - Fix a synchronization problem between fallocate and aio dio
     corrupting the file length

   - Clean up various loose ends in the iomap and bmap code

   - Convert to the new mount api

   - Make sure we always log something when returning EFSCORRUPTED

   - Fix some problems where long running scrub loops could trigger soft
     lockup warnings and/or fail to exit due to fatal signals pending

   - Fix various Coverity complaints

   - Remove most of the function pointers from the directory code to
     reduce indirection penalties

   - Ensure that dquots are attached to the inode when performing
     unwritten extent conversion after io

   - Deuglify incore projid and crtime types

   - Fix another AGI/AGF locking order deadlock when renaming

   - Clean up some quota typedefs

   - Remove the FSSETDM ioctls which haven't done anything in 20 years

   - Fix some memory leaks when mounting the log fails

   - Fix an underflow when updating an xattr leaf freemap

   - Remove some trivial wrappers

   - Report metadata corruption as an error, not a (potentially) fatal
     assertion

   - Clean up the dir/attr buffer mapping code

   - Allow fatal signals to kill scrub during parent pointer checks"

* tag 'xfs-5.5-merge-16' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (198 commits)
  xfs: allow parent directory scans to be interrupted with fatal signals
  xfs: remove the mappedbno argument to xfs_da_get_buf
  xfs: remove the mappedbno argument to xfs_da_read_buf
  xfs: split xfs_da3_node_read
  xfs: remove the mappedbno argument to xfs_dir3_leafn_read
  xfs: remove the mappedbno argument to xfs_dir3_leaf_read
  xfs: remove the mappedbno argument to xfs_attr3_leaf_read
  xfs: remove the mappedbno argument to xfs_da_reada_buf
  xfs: improve the xfs_dabuf_map calling conventions
  xfs: refactor xfs_dabuf_map
  xfs: simplify mappedbno handling in xfs_da_{get,read}_buf
  xfs: report corruption only as a regular error
  xfs: Remove kmem_zone_free() wrapper
  xfs: Remove kmem_zone_destroy() wrapper
  xfs: Remove slab init wrappers
  xfs: fix attr leaf header freemap.size underflow
  xfs: fix some memory leaks in log recovery
  xfs: fix another missing include
  xfs: remove XFS_IOC_FSSETDM and XFS_IOC_FSSETDM_BY_HANDLE
  xfs: remove duplicated include from xfs_dir2_data.c
  ...
Commit
97eeb4d9d755605385fa329da9afa38729f3413c
Parents
9b326948 · 8feb4732

Merge commit. Changes below are compared with the first parent: 9b326948.

Changes

126 files changed · +5828 −6271

FileStatusAddDelContent
fs/compat_ioctl.cmodified+14−2View file
fs/ioctl.cmodified+11−5View file
fs/xfs/Makefilemodified+0−1View file
fs/xfs/kmem.cmodified+1−1View file
fs/xfs/kmem.hmodified+0−30View file
fs/xfs/libxfs/xfs_ag_resv.cmodified+2−0View file
fs/xfs/libxfs/xfs_alloc.cmodified+744−492View file
fs/xfs/libxfs/xfs_alloc.hmodified+1−15View file
fs/xfs/libxfs/xfs_alloc_btree.cmodified+1−0View file
fs/xfs/libxfs/xfs_attr.cmodified+11−13View file
fs/xfs/libxfs/xfs_attr_leaf.cmodified+102−32View file
fs/xfs/libxfs/xfs_attr_leaf.hmodified+26−4View file
fs/xfs/libxfs/xfs_attr_remote.cmodified+1−0View file
fs/xfs/libxfs/xfs_bit.cmodified+1−0View file
fs/xfs/libxfs/xfs_bmap.cmodified+396−290View file
fs/xfs/libxfs/xfs_btree.cmodified+57−40View file
fs/xfs/libxfs/xfs_btree.hmodified+28−9View file
fs/xfs/libxfs/xfs_da_btree.cmodified+315−353View file
fs/xfs/libxfs/xfs_da_btree.hmodified+48−25View file
fs/xfs/libxfs/xfs_da_format.cdeleted+0−888View before deletion
fs/xfs/libxfs/xfs_da_format.hmodified+1−58View file
fs/xfs/libxfs/xfs_dir2.cmodified+40−32View file
fs/xfs/libxfs/xfs_dir2.hmodified+6−84View file
fs/xfs/libxfs/xfs_dir2_block.cmodified+61−70View file
fs/xfs/libxfs/xfs_dir2_data.cmodified+155−127View file
fs/xfs/libxfs/xfs_dir2_leaf.cmodified+171−136View file
fs/xfs/libxfs/xfs_dir2_node.cmodified+235−196View file
fs/xfs/libxfs/xfs_dir2_priv.hmodified+103−11View file
fs/xfs/libxfs/xfs_dir2_sf.cmodified+254−170View file
fs/xfs/libxfs/xfs_dquot_buf.cmodified+4−4View file
fs/xfs/libxfs/xfs_format.hmodified+7−7View file
fs/xfs/libxfs/xfs_fs.hmodified+2−2View file
fs/xfs/libxfs/xfs_ialloc.cmodified+86−31View file
fs/xfs/libxfs/xfs_iext_tree.cmodified+1−1View file
fs/xfs/libxfs/xfs_inode_buf.cmodified+9−12View file
fs/xfs/libxfs/xfs_inode_buf.hmodified+2−3View file
fs/xfs/libxfs/xfs_inode_fork.cmodified+14−8View file
fs/xfs/libxfs/xfs_inode_fork.hmodified+12−6View file
fs/xfs/libxfs/xfs_log_format.hmodified+2−2View file
fs/xfs/libxfs/xfs_log_recover.hmodified+2−2View file
fs/xfs/libxfs/xfs_refcount.cmodified+126−48View file
fs/xfs/libxfs/xfs_rmap.cmodified+289−88View file
fs/xfs/libxfs/xfs_rtbitmap.cmodified+2−2View file
fs/xfs/libxfs/xfs_sb.cmodified+1−0View file
fs/xfs/libxfs/xfs_trans_inode.cmodified+3−5View file
fs/xfs/libxfs/xfs_trans_resv.cmodified+3−3View file
fs/xfs/libxfs/xfs_types.hmodified+0−2View file
fs/xfs/scrub/attr.cmodified+6−5View file
fs/xfs/scrub/bitmap.cmodified+2−1View file
fs/xfs/scrub/common.hmodified+8−1View file
fs/xfs/scrub/dabtree.cmodified+17−45View file
fs/xfs/scrub/dabtree.hmodified+1−2View file
fs/xfs/scrub/dir.cmodified+68−64View file
fs/xfs/scrub/fscounters.cmodified+6−2View file
fs/xfs/scrub/health.cmodified+1−0View file
fs/xfs/scrub/parent.cmodified+21−6View file
fs/xfs/scrub/quota.cmodified+7−0View file
fs/xfs/scrub/scrub.cmodified+1−0View file
fs/xfs/xfs_acl.cmodified+14−4View file
fs/xfs/xfs_aops.cmodified+10−33View file
fs/xfs/xfs_aops.hmodified+0−3View file
fs/xfs/xfs_attr_inactive.cmodified+46−30View file
fs/xfs/xfs_attr_list.cmodified+46−29View file
fs/xfs/xfs_bmap_item.cmodified+6−5View file
fs/xfs/xfs_bmap_util.cmodified+41−214View file
fs/xfs/xfs_bmap_util.hmodified+0−4View file
fs/xfs/xfs_buf.cmodified+15−17View file
fs/xfs/xfs_buf.hmodified+0−1View file
fs/xfs/xfs_buf_item.cmodified+3−3View file
fs/xfs/xfs_dir2_readdir.cmodified+73−64View file
fs/xfs/xfs_discard.cmodified+5−1View file
fs/xfs/xfs_dquot.cmodified+24−22View file
fs/xfs/xfs_dquot.hmodified+50−48View file
fs/xfs/xfs_dquot_item.hmodified+18−16View file
fs/xfs/xfs_error.cmodified+26−5View file
fs/xfs/xfs_error.hmodified+4−29View file
fs/xfs/xfs_extent_busy.cmodified+1−1View file
fs/xfs/xfs_extfree_item.cmodified+5−4View file
fs/xfs/xfs_file.cmodified+78−26View file
fs/xfs/xfs_filestream.cmodified+2−1View file
fs/xfs/xfs_fsmap.cmodified+1−0View file
fs/xfs/xfs_icache.cmodified+4−4View file
fs/xfs/xfs_icreate_item.cmodified+1−1View file
fs/xfs/xfs_inode.cmodified+39−9View file
fs/xfs/xfs_inode.hmodified+8−23View file
fs/xfs/xfs_inode_item.cmodified+9−6View file
fs/xfs/xfs_ioctl.cmodified+27−176View file
fs/xfs/xfs_ioctl.hmodified+0−7View file
fs/xfs/xfs_ioctl32.cmodified+2−47View file
fs/xfs/xfs_ioctl32.hmodified+2−11View file
fs/xfs/xfs_iomap.cmodified+427−435View file
fs/xfs/xfs_iomap.hmodified+7−4View file
fs/xfs/xfs_iops.cmodified+48−22View file
fs/xfs/xfs_itable.cmodified+3−3View file
fs/xfs/xfs_iwalk.cmodified+2−1View file
fs/xfs/xfs_linux.hmodified+10−4View file
fs/xfs/xfs_log.cmodified+175−259View file
fs/xfs/xfs_log_cil.cmodified+3−3View file
fs/xfs/xfs_log_priv.hmodified+15−18View file
fs/xfs/xfs_log_recover.cmodified+77−71View file
fs/xfs/xfs_message.cmodified+15−7View file
fs/xfs/xfs_message.hmodified+3−3View file
fs/xfs/xfs_mount.cmodified+10−48View file
fs/xfs/xfs_mount.hmodified+4−53View file
fs/xfs/xfs_pnfs.cmodified+26−30View file
fs/xfs/xfs_qm.cmodified+36−31View file
fs/xfs/xfs_qm.hmodified+3−3View file
fs/xfs/xfs_qm_bhv.cmodified+4−4View file
fs/xfs/xfs_qm_syscalls.cmodified+67−72View file
fs/xfs/xfs_quotaops.cmodified+3−0View file
fs/xfs/xfs_refcount_item.cmodified+5−4View file
fs/xfs/xfs_reflink.cmodified+23−115View file
fs/xfs/xfs_reflink.hmodified+2−2View file
fs/xfs/xfs_rmap_item.cmodified+8−5View file
fs/xfs/xfs_rtalloc.cmodified+1−2View file
fs/xfs/xfs_super.cmodified+715−751View file
fs/xfs/xfs_super.hmodified+10−0View file
fs/xfs/xfs_symlink.cmodified+1−0View file
fs/xfs/xfs_symlink.hmodified+1−1View file
fs/xfs/xfs_trace.hmodified+32−3View file
fs/xfs/xfs_trans.cmodified+1−1View file
fs/xfs/xfs_trans_ail.cmodified+5−5View file
fs/xfs/xfs_trans_dquot.cmodified+28−28View file
fs/xfs/xfs_xattr.cmodified+1−0View file
include/linux/falloc.hmodified+8−2View file
include/linux/fs.hmodified+1−1View file

Only the first 600 diff lines are shown. Download the complete patch.

fs/compat_ioctl.c

View file
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 9ae90d7..358ea2e 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -185,15 +185,27 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
/* handled by some ->ioctl(); always a pointer to int */
case FIONREAD:
goto found_handler;
- /* these two get messy on amd64 due to alignment differences */
+ /* these get messy on amd64 due to alignment differences */
#if defined(CONFIG_X86_64)
case FS_IOC_RESVSP_32:
case FS_IOC_RESVSP64_32:
- error = compat_ioctl_preallocate(f.file, compat_ptr(arg));
+ error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
+ goto out_fput;
+ case FS_IOC_UNRESVSP_32:
+ case FS_IOC_UNRESVSP64_32:
+ error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
+ compat_ptr(arg));
+ goto out_fput;
+ case FS_IOC_ZERO_RANGE_32:
+ error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
+ compat_ptr(arg));
goto out_fput;
#else
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
+ case FS_IOC_UNRESVSP:
+ case FS_IOC_UNRESVSP64:
+ case FS_IOC_ZERO_RANGE:
goto found_handler;
#endif

fs/ioctl.c

View file
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 812061b..2f5e4e5 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -467,7 +467,7 @@ EXPORT_SYMBOL(generic_block_fiemap);
* Only the l_start, l_len and l_whence fields of the 'struct space_resv'
* are used here, rest are ignored.
*/
-int ioctl_preallocate(struct file *filp, void __user *argp)
+int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
{
struct inode *inode = file_inode(filp);
struct space_resv sr;
@@ -488,13 +488,14 @@ int ioctl_preallocate(struct file *filp, void __user *argp)
return -EINVAL;
}
- return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
+ return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
+ sr.l_len);
}
/* on ia32 l_start is on a 32-bit boundary */
#if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
/* just account for different alignment */
-int compat_ioctl_preallocate(struct file *file,
+int compat_ioctl_preallocate(struct file *file, int mode,
struct space_resv_32 __user *argp)
{
struct inode *inode = file_inode(file);
@@ -516,7 +517,7 @@ int compat_ioctl_preallocate(struct file *file,
return -EINVAL;
}
- return vfs_fallocate(file, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
+ return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
}
#endif
@@ -533,7 +534,12 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return put_user(i_size_read(inode) - filp->f_pos, p);
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
- return ioctl_preallocate(filp, p);
+ return ioctl_preallocate(filp, 0, p);
+ case FS_IOC_UNRESVSP:
+ case FS_IOC_UNRESVSP64:
+ return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
+ case FS_IOC_ZERO_RANGE:
+ return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
}
return vfs_ioctl(filp, cmd, arg);

fs/xfs/Makefile

View file
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 06b68b6..aceca2f 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -27,7 +27,6 @@ xfs-y += $(addprefix libxfs/, \
xfs_bmap_btree.o \
xfs_btree.o \
xfs_da_btree.o \
- xfs_da_format.o \
xfs_defer.o \
xfs_dir2.o \
xfs_dir2_block.o \

fs/xfs/kmem.c

View file
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index da031b9..1da9423 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -32,7 +32,7 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
/*
- * __vmalloc() will allocate data pages and auxillary structures (e.g.
+ * __vmalloc() will allocate data pages and auxiliary structures (e.g.
* pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context here. Hence
* we need to tell memory reclaim that we are in such a context via
* PF_MEMALLOC_NOFS to prevent memory reclaim re-entering the filesystem here

fs/xfs/kmem.h

View file
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index 8170d95..6143117 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -78,39 +78,9 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
* Zone interfaces
*/
-#define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN
-#define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT
-#define KM_ZONE_SPREAD SLAB_MEM_SPREAD
-#define KM_ZONE_ACCOUNT SLAB_ACCOUNT
-
#define kmem_zone kmem_cache
#define kmem_zone_t struct kmem_cache
-static inline kmem_zone_t *
-kmem_zone_init(int size, char *zone_name)
-{
- return kmem_cache_create(zone_name, size, 0, 0, NULL);
-}
-
-static inline kmem_zone_t *
-kmem_zone_init_flags(int size, char *zone_name, slab_flags_t flags,
- void (*construct)(void *))
-{
- return kmem_cache_create(zone_name, size, 0, flags, construct);
-}
-
-static inline void
-kmem_zone_free(kmem_zone_t *zone, void *ptr)
-{
- kmem_cache_free(zone, ptr);
-}
-
-static inline void
-kmem_zone_destroy(kmem_zone_t *zone)
-{
- kmem_cache_destroy(zone);
-}
-
extern void *kmem_zone_alloc(kmem_zone_t *, xfs_km_flags_t);
static inline void *

fs/xfs/libxfs/xfs_ag_resv.c

View file
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c
index 87a9747..fdfe6dc 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.c
+++ b/fs/xfs/libxfs/xfs_ag_resv.c
@@ -19,6 +19,8 @@
#include "xfs_btree.h"
#include "xfs_refcount_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_sb.h"
+#include "xfs_ag_resv.h"
/*
* Per-AG Block Reservations

fs/xfs/libxfs/xfs_alloc.c

View file
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 533b04a..c284e10 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -146,9 +146,13 @@ xfs_alloc_lookup_eq(
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
+ int error;
+
cur->bc_rec.a.ar_startblock = bno;
cur->bc_rec.a.ar_blockcount = len;
- return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
+ cur->bc_private.a.priv.abt.active = (*stat == 1);
+ return error;
}
/*
@@ -162,9 +166,13 @@ xfs_alloc_lookup_ge(
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
+ int error;
+
cur->bc_rec.a.ar_startblock = bno;
cur->bc_rec.a.ar_blockcount = len;
- return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
+ cur->bc_private.a.priv.abt.active = (*stat == 1);
+ return error;
}
/*
@@ -178,9 +186,19 @@ xfs_alloc_lookup_le(
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
+ int error;
cur->bc_rec.a.ar_startblock = bno;
cur->bc_rec.a.ar_blockcount = len;
- return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
+ cur->bc_private.a.priv.abt.active = (*stat == 1);
+ return error;
+}
+
+static inline bool
+xfs_alloc_cur_active(
+ struct xfs_btree_cur *cur)
+{
+ return cur && cur->bc_private.a.priv.abt.active;
}
/*
@@ -313,7 +331,7 @@ xfs_alloc_compute_diff(
xfs_extlen_t newlen1=0; /* length with newbno1 */
xfs_extlen_t newlen2=0; /* length with newbno2 */
xfs_agblock_t wantend; /* end of target extent */
- bool userdata = xfs_alloc_is_userdata(datatype);
+ bool userdata = datatype & XFS_ALLOC_USERDATA;
ASSERT(freelen >= wantlen);
freeend = freebno + freelen;
@@ -433,13 +451,17 @@ xfs_alloc_fixup_trees(
#ifdef DEBUG
if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp,
- i == 1 && nfbno1 == fbno && nflen1 == flen);
+ if (XFS_IS_CORRUPT(mp,
+ i != 1 ||
+ nfbno1 != fbno ||
+ nflen1 != flen))
+ return -EFSCORRUPTED;
#endif
} else {
if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
}
/*
* Look up the record in the by-block tree if necessary.
@@ -448,13 +470,17 @@ xfs_alloc_fixup_trees(
#ifdef DEBUG
if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp,
- i == 1 && nfbno1 == fbno && nflen1 == flen);
+ if (XFS_IS_CORRUPT(mp,
+ i != 1 ||
+ nfbno1 != fbno ||
+ nflen1 != flen))
+ return -EFSCORRUPTED;
#endif
} else {
if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
}
#ifdef DEBUG
@@ -465,8 +491,10 @@ xfs_alloc_fixup_trees(
bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
- XFS_WANT_CORRUPTED_RETURN(mp,
- bnoblock->bb_numrecs == cntblock->bb_numrecs);
+ if (XFS_IS_CORRUPT(mp,
+ bnoblock->bb_numrecs !=
+ cntblock->bb_numrecs))
+ return -EFSCORRUPTED;
}
#endif
@@ -496,25 +524,30 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_btree_delete(cnt_cur, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
/*
* Add new by-size btree entry(s).
*/
if (nfbno1 != NULLAGBLOCK) {
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
+ if (XFS_IS_CORRUPT(mp, i != 0))
+ return -EFSCORRUPTED;
if ((error = xfs_btree_insert(cnt_cur, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
}
if (nfbno2 != NULLAGBLOCK) {
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
+ if (XFS_IS_CORRUPT(mp, i != 0))
+ return -EFSCORRUPTED;
if ((error = xfs_btree_insert(cnt_cur, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
}
/*
* Fix up the by-block btree entry(s).
@@ -525,7 +558,8 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_btree_delete(bno_cur, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
} else {
/*
* Update the by-block entry to start later|be shorter.
@@ -539,10 +573,12 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
+ if (XFS_IS_CORRUPT(mp, i != 0))
+ return -EFSCORRUPTED;
if ((error = xfs_btree_insert(bno_cur, &i)))
return error;
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+ if (XFS_IS_CORRUPT(mp, i != 1))
+ return -EFSCORRUPTED;
}
return 0;
}
@@ -684,16 +720,298 @@ xfs_alloc_update_counters(
xfs_trans_agblocks_delta(tp, len);
if (unlikely(be32_to_cpu(agf->agf_freeblks) >
- be32_to_cpu(agf->agf_length)))
+ be32_to_cpu(agf->agf_length))) {
+ xfs_buf_corruption_error(agbp);
return -EFSCORRUPTED;
+ }
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
return 0;
}
/*
- * Allocation group level functions.
+ * Block allocation algorithm and data structures.
+ */
+struct xfs_alloc_cur {
+ struct xfs_btree_cur *cnt; /* btree cursors */
+ struct xfs_btree_cur *bnolt;
+ struct xfs_btree_cur *bnogt;
+ xfs_extlen_t cur_len;/* current search length */
+ xfs_agblock_t rec_bno;/* extent startblock */
+ xfs_extlen_t rec_len;/* extent length */
+ xfs_agblock_t bno; /* alloc bno */
+ xfs_extlen_t len; /* alloc len */
+ xfs_extlen_t diff; /* diff from search bno */
+ unsigned int busy_gen;/* busy state */
+ bool busy;
+};
+
+/*
+ * Set up cursors, etc. in the extent allocation cursor. This function can be
+ * called multiple times to reset an initialized structure without having to
+ * reallocate cursors.
+ */
+static int
+xfs_alloc_cur_setup(
+ struct xfs_alloc_arg *args,
+ struct xfs_alloc_cur *acur)
+{
+ int error;
+ int i;
+
+ ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO);
+
+ acur->cur_len = args->maxlen;
+ acur->rec_bno = 0;
+ acur->rec_len = 0;
+ acur->bno = 0;
+ acur->len = 0;
+ acur->diff = -1;
+ acur->busy = false;
+ acur->busy_gen = 0;
+
+ /*
+ * Perform an initial cntbt lookup to check for availability of maxlen
+ * extents. If this fails, we'll return -ENOSPC to signal the caller to
+ * attempt a small allocation.
+ */
+ if (!acur->cnt)
+ acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp,
+ args->agbp, args->agno, XFS_BTNUM_CNT);
+ error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i);
+ if (error)
+ return error;
+
+ /*
+ * Allocate the bnobt left and right search cursors.
+ */
+ if (!acur->bnolt)
+ acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp,
+ args->agbp, args->agno, XFS_BTNUM_BNO);
+ if (!acur->bnogt)
+ acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp,
+ args->agbp, args->agno, XFS_BTNUM_BNO);
+ return i == 1 ? 0 : -ENOSPC;
+}
+
+static void
+xfs_alloc_cur_close(
+ struct xfs_alloc_cur *acur,
+ bool error)
+{
+ int cur_error = XFS_BTREE_NOERROR;
+
+ if (error)
+ cur_error = XFS_BTREE_ERROR;
+
+ if (acur->cnt)
+ xfs_btree_del_cursor(acur->cnt, cur_error);
+ if (acur->bnolt)
+ xfs_btree_del_cursor(acur->bnolt, cur_error);
+ if (acur->bnogt)
+ xfs_btree_del_cursor(acur->bnogt, cur_error);
+ acur->cnt = acur->bnolt = acur->bnogt = NULL;
+}
+
+/*
+ * Check an extent for allocation and track the best available candidate in the
+ * allocation structure. The cursor is deactivated if it has entered an out of
+ * range state based on allocation arguments. Optionally return the extent
+ * extent geometry and allocation status if requested by the caller.
+ */
+static int
+xfs_alloc_cur_check(
+ struct xfs_alloc_arg *args,
+ struct xfs_alloc_cur *acur,
+ struct xfs_btree_cur *cur,
+ int *new)
+{
+ int error, i;
+ xfs_agblock_t bno, bnoa, bnew;
+ xfs_extlen_t len, lena, diff = -1;
+ bool busy;
+ unsigned busy_gen = 0;
+ bool deactivate = false;
+ bool isbnobt = cur->bc_btnum == XFS_BTNUM_BNO;
+
+ *new = 0;
+
+ error = xfs_alloc_get_rec(cur, &bno, &len, &i);
+ if (error)
+ return error;
+ if (XFS_IS_CORRUPT(args->mp, i != 1))
+ return -EFSCORRUPTED;
+
+ /*
+ * Check minlen and deactivate a cntbt cursor if out of acceptable size
+ * range (i.e., walking backwards looking for a minlen extent).
+ */
+ if (len < args->minlen) {
+ deactivate = !isbnobt;
+ goto out;
+ }
+
+ busy = xfs_alloc_compute_aligned(args, bno, len, &bnoa, &lena,
+ &busy_gen);
+ acur->busy |= busy;
+ if (busy)
+ acur->busy_gen = busy_gen;
+ /* deactivate a bnobt cursor outside of locality range */
+ if (bnoa < args->min_agbno || bnoa > args->max_agbno) {
+ deactivate = isbnobt;
+ goto out;
+ }
+ if (lena < args->minlen)
+ goto out;
+
+ args->len = XFS_EXTLEN_MIN(lena, args->maxlen);
+ xfs_alloc_fix_len(args);
+ ASSERT(args->len >= args->minlen);
+ if (args->len < acur->len)
+ goto out;
+
+ /*
+ * We have an aligned record that satisfies minlen and beats or matches
+ * the candidate extent size. Compare locality for near allocation mode.
+ */
+ ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO);
+ diff = xfs_alloc_compute_diff(args->agbno, args->len,
+ args->alignment, args->datatype,
+ bnoa, lena, &bnew);
+ if (bnew == NULLAGBLOCK)
+ goto out;
+
+ /*
+ * Deactivate a bnobt cursor with worse locality than the current best.
+ */
+ if (diff > acur->diff) {
+ deactivate = isbnobt;
+ goto out;
+ }
+
+ ASSERT(args->len > acur->len ||
+ (args->len == acur->len && diff <= acur->diff));
+ acur->rec_bno = bno;
+ acur->rec_len = len;
+ acur->bno = bnew;
+ acur->len = args->len;
+ acur->diff = diff;
+ *new = 1;
+
+ /*
+ * We're done if we found a perfect allocation. This only deactivates
+ * the current cursor, but this is just an optimization to terminate a
+ * cntbt search that otherwise runs to the edge of the tree.
+ */
+ if (acur->diff == 0 && acur->len == args->maxlen)
+ deactivate = true;
+out:
+ if (deactivate)
+ cur->bc_private.a.priv.abt.active = false;
+ trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
+ *new);
+ return 0;
+}
+
+/*
+ * Complete an allocation of a candidate extent. Remove the extent from both
+ * trees and update the args structure.
*/
+STATIC int
+xfs_alloc_cur_finish(
+ struct xfs_alloc_arg *args,
+ struct xfs_alloc_cur *acur)
+{
+ int error;
+
+ ASSERT(acur->cnt && acur->bnolt);
+ ASSERT(acur->bno >= acur->rec_bno);
+ ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len);
+ ASSERT(acur->rec_bno + acur->rec_len <=
+ be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
+
+ error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno,
+ acur->rec_len, acur->bno, acur->len, 0);
+ if (error)
+ return error;
+
+ args->agbno = acur->bno;
+ args->len = acur->len;
+ args->wasfromfl = 0;
+
+ trace_xfs_alloc_cur(args);
+ return 0;
+}
+
+/*
+ * Locality allocation lookup algorithm. This expects a cntbt cursor and uses
+ * bno optimized lookup to search for extents with ideal size and locality.
+ */
+STATIC int
+xfs_alloc_cntbt_iter(
+ struct xfs_alloc_arg *args,
+ struct xfs_alloc_cur *acur)
+{
+ struct xfs_btree_cur *cur = acur->cnt;
+ xfs_agblock_t bno;
+ xfs_extlen_t len, cur_len;
+ int error;
+ int i;
+
+ if (!xfs_alloc_cur_active(cur))
+ return 0;
+
+ /* locality optimized lookup */
+ cur_len = acur->cur_len;
+ error = xfs_alloc_lookup_ge(cur, args->agbno, cur_len, &i);
+ if (error)

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_alloc.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_alloc_btree.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_attr.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_attr_leaf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_attr_leaf.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_attr_remote.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_bit.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_bmap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_btree.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_btree.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_da_btree.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_da_btree.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_da_format.c

View before deletion

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_da_format.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_block.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_data.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_leaf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_node.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_priv.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dir2_sf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_dquot_buf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_format.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_fs.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_ialloc.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_iext_tree.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_inode_buf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_inode_buf.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_inode_fork.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_inode_fork.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_log_format.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_log_recover.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_refcount.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_rmap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_rtbitmap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_sb.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_trans_inode.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_trans_resv.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/libxfs/xfs_types.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/attr.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/bitmap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/common.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/dabtree.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/dabtree.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/dir.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/fscounters.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/health.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/parent.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/quota.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/scrub/scrub.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_acl.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_aops.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_aops.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_attr_inactive.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_attr_list.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_bmap_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_bmap_util.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_bmap_util.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_buf.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_buf.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_buf_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_dir2_readdir.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_discard.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_dquot.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_dquot.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_dquot_item.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_error.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_error.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_extent_busy.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_extfree_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_file.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_filestream.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_fsmap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_icache.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_icreate_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_inode.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_inode.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_inode_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_ioctl.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_ioctl.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_ioctl32.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_ioctl32.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_iomap.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_iomap.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_iops.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_itable.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_iwalk.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_linux.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_log.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_log_cil.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_log_priv.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_log_recover.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_message.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_message.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_mount.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_mount.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_pnfs.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_qm.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_qm.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_qm_bhv.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_qm_syscalls.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_quotaops.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_refcount_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_reflink.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_reflink.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_rmap_item.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_rtalloc.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_super.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_super.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_symlink.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_symlink.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_trace.h

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_trans.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_trans_ail.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_trans_dquot.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_xattr.c

View file

This diff is incomplete. Download the complete patch.

include/linux/falloc.h

View file

This diff is incomplete. Download the complete patch.

include/linux/fs.h

View file

This diff is incomplete. Download the complete patch.