aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 19:15:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 19:15:17 -0500
commitae90fb14206efda2c2ea6d61e14f14bf0132f676 (patch)
treef8ec87d501ec4d091177b8916d0e0c81e570454c /fs/xfs
parentc5452a58db9bbcb331ee92afa99a6f42e39085c7 (diff)
parentbad962662dbc60e76ec1baae34af56b1ba2dfa5f (diff)
Merge tag 'xfs-for-linus-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs
Pull xfs update from Dave Chinner: "This update contains: - RENAME_EXCHANGE support - Rework of the superblock logging infrastructure - Rework of the XFS_IOCTL_SETXATTR implementation * enables use inside user namespaces * fixes inconsistencies setting extent size hints - fixes for missing buffer type annotations used in log recovery - more consolidation of libxfs headers - preparation patches for block based PNFS support - miscellaneous bug fixes and cleanups" * tag 'xfs-for-linus-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: (37 commits) xfs: only trace buffer items if they exist xfs: report proper f_files in statfs if we overshoot imaxpct xfs: fix panic_mask documentation xfs: xfs_ioctl_setattr_check_projid can be static xfs: growfs should use synchronous transactions xfs: fix behaviour of XFS_IOC_FSSETXATTR on directories xfs: factor projid hint checking out of xfs_ioctl_setattr xfs: factor extsize hint checking out of xfs_ioctl_setattr xfs: XFS_IOCTL_SETXATTR can run in user namespaces xfs: kill xfs_ioctl_setattr behaviour mask xfs: disaggregate xfs_ioctl_setattr xfs: factor out xfs_ioctl_setattr transaciton preamble xfs: separate xflags from xfs_ioctl_setattr xfs: FSX_NONBLOCK is not used xfs: don't allocate an ioend for direct I/O completions xfs: change kmem_free to use generic kvfree() xfs: factor out a xfs_update_prealloc_flags() helper xfs: remove incorrect error negation in attr_multi ioctl xfs: set superblock buffer type correctly xfs: set buf types when converting extent formats ...
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/kmem.c10
-rw-r--r--fs/xfs/kmem.h5
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c20
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h33
-rw-r--r--fs/xfs/libxfs/xfs_format.h24
-rw-r--r--fs/xfs/libxfs/xfs_fs.h (renamed from fs/xfs/xfs_fs.h)0
-rw-r--r--fs/xfs/libxfs/xfs_sb.c320
-rw-r--r--fs/xfs/libxfs/xfs_sb.h11
-rw-r--r--fs/xfs/libxfs/xfs_shared.h33
-rw-r--r--fs/xfs/libxfs/xfs_symlink_remote.c2
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.c14
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.h1
-rw-r--r--fs/xfs/libxfs/xfs_types.h (renamed from fs/xfs/xfs_types.h)0
-rw-r--r--fs/xfs/xfs_aops.c149
-rw-r--r--fs/xfs/xfs_aops.h3
-rw-r--r--fs/xfs/xfs_bmap_util.h37
-rw-r--r--fs/xfs/xfs_buf_item.c6
-rw-r--r--fs/xfs/xfs_dquot.h2
-rw-r--r--fs/xfs/xfs_file.c64
-rw-r--r--fs/xfs/xfs_fsops.c34
-rw-r--r--fs/xfs/xfs_inode.c136
-rw-r--r--fs/xfs/xfs_inode.h11
-rw-r--r--fs/xfs/xfs_ioctl.c501
-rw-r--r--fs/xfs/xfs_ioctl32.c2
-rw-r--r--fs/xfs/xfs_iomap.c2
-rw-r--r--fs/xfs/xfs_iomap.h2
-rw-r--r--fs/xfs/xfs_iops.c21
-rw-r--r--fs/xfs/xfs_log.c28
-rw-r--r--fs/xfs/xfs_mount.c107
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_qm.c43
-rw-r--r--fs/xfs/xfs_qm.h1
-rw-r--r--fs/xfs/xfs_qm_syscalls.c14
-rw-r--r--fs/xfs/xfs_super.c20
-rw-r--r--fs/xfs/xfs_sysctl.c18
-rw-r--r--fs/xfs/xfs_trans.c1
-rw-r--r--fs/xfs/xfs_trans_buf.c5
38 files changed, 807 insertions, 880 deletions
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index 53e95b2a1369..a7a3a63bb360 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -91,16 +91,6 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
91 return ptr; 91 return ptr;
92} 92}
93 93
94void
95kmem_free(const void *ptr)
96{
97 if (!is_vmalloc_addr(ptr)) {
98 kfree(ptr);
99 } else {
100 vfree(ptr);
101 }
102}
103
104void * 94void *
105kmem_realloc(const void *ptr, size_t newsize, size_t oldsize, 95kmem_realloc(const void *ptr, size_t newsize, size_t oldsize,
106 xfs_km_flags_t flags) 96 xfs_km_flags_t flags)
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index 64db0e53edea..cc6b768fc068 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -63,7 +63,10 @@ kmem_flags_convert(xfs_km_flags_t flags)
63extern void *kmem_alloc(size_t, xfs_km_flags_t); 63extern void *kmem_alloc(size_t, xfs_km_flags_t);
64extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t); 64extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
65extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); 65extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t);
66extern void kmem_free(const void *); 66static inline void kmem_free(const void *ptr)
67{
68 kvfree(ptr);
69}
67 70
68 71
69extern void *kmem_zalloc_greedy(size_t *, size_t, size_t); 72extern void *kmem_zalloc_greedy(size_t *, size_t, size_t);
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 5d38e8b8a913..15105dbc9e28 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -403,7 +403,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
403 if (!xfs_sb_version_hasattr2(&mp->m_sb)) { 403 if (!xfs_sb_version_hasattr2(&mp->m_sb)) {
404 xfs_sb_version_addattr2(&mp->m_sb); 404 xfs_sb_version_addattr2(&mp->m_sb);
405 spin_unlock(&mp->m_sb_lock); 405 spin_unlock(&mp->m_sb_lock);
406 xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 406 xfs_log_sb(tp);
407 } else 407 } else
408 spin_unlock(&mp->m_sb_lock); 408 spin_unlock(&mp->m_sb_lock);
409 } 409 }
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index b5eb4743f75a..61ec015dca16 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -973,7 +973,11 @@ xfs_bmap_local_to_extents(
973 *firstblock = args.fsbno; 973 *firstblock = args.fsbno;
974 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); 974 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
975 975
976 /* initialise the block and copy the data */ 976 /*
977 * Initialise the block and copy the data
978 *
979 * Note: init_fn must set the buffer log item type correctly!
980 */
977 init_fn(tp, bp, ip, ifp); 981 init_fn(tp, bp, ip, ifp);
978 982
979 /* account for the change in fork size and log everything */ 983 /* account for the change in fork size and log everything */
@@ -1221,22 +1225,20 @@ xfs_bmap_add_attrfork(
1221 goto bmap_cancel; 1225 goto bmap_cancel;
1222 if (!xfs_sb_version_hasattr(&mp->m_sb) || 1226 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
1223 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { 1227 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
1224 __int64_t sbfields = 0; 1228 bool log_sb = false;
1225 1229
1226 spin_lock(&mp->m_sb_lock); 1230 spin_lock(&mp->m_sb_lock);
1227 if (!xfs_sb_version_hasattr(&mp->m_sb)) { 1231 if (!xfs_sb_version_hasattr(&mp->m_sb)) {
1228 xfs_sb_version_addattr(&mp->m_sb); 1232 xfs_sb_version_addattr(&mp->m_sb);
1229 sbfields |= XFS_SB_VERSIONNUM; 1233 log_sb = true;
1230 } 1234 }
1231 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { 1235 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
1232 xfs_sb_version_addattr2(&mp->m_sb); 1236 xfs_sb_version_addattr2(&mp->m_sb);
1233 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 1237 log_sb = true;
1234 } 1238 }
1235 if (sbfields) { 1239 spin_unlock(&mp->m_sb_lock);
1236 spin_unlock(&mp->m_sb_lock); 1240 if (log_sb)
1237 xfs_mod_sb(tp, sbfields); 1241 xfs_log_sb(tp);
1238 } else
1239 spin_unlock(&mp->m_sb_lock);
1240 } 1242 }
1241 1243
1242 error = xfs_bmap_finish(&tp, &flist, &committed); 1244 error = xfs_bmap_finish(&tp, &flist, &committed);
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index 44db6db86402..b9d8a499d2c4 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -28,6 +28,37 @@ struct xfs_trans;
28extern kmem_zone_t *xfs_bmap_free_item_zone; 28extern kmem_zone_t *xfs_bmap_free_item_zone;
29 29
30/* 30/*
31 * Argument structure for xfs_bmap_alloc.
32 */
33struct xfs_bmalloca {
34 xfs_fsblock_t *firstblock; /* i/o first block allocated */
35 struct xfs_bmap_free *flist; /* bmap freelist */
36 struct xfs_trans *tp; /* transaction pointer */
37 struct xfs_inode *ip; /* incore inode pointer */
38 struct xfs_bmbt_irec prev; /* extent before the new one */
39 struct xfs_bmbt_irec got; /* extent after, or delayed */
40
41 xfs_fileoff_t offset; /* offset in file filling in */
42 xfs_extlen_t length; /* i/o length asked/allocated */
43 xfs_fsblock_t blkno; /* starting block of new extent */
44
45 struct xfs_btree_cur *cur; /* btree cursor */
46 xfs_extnum_t idx; /* current extent index */
47 int nallocs;/* number of extents alloc'd */
48 int logflags;/* flags for transaction logging */
49
50 xfs_extlen_t total; /* total blocks needed for xaction */
51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */
52 xfs_extlen_t minleft; /* amount must be left after alloc */
53 bool eof; /* set if allocating past last extent */
54 bool wasdel; /* replacing a delayed allocation */
55 bool userdata;/* set if is user data */
56 bool aeof; /* allocated space at eof */
57 bool conv; /* overwriting unwritten extents */
58 int flags;
59};
60
61/*
31 * List of extents to be free "later". 62 * List of extents to be free "later".
32 * The list is kept sorted on xbf_startblock. 63 * The list is kept sorted on xbf_startblock.
33 */ 64 */
@@ -149,6 +180,8 @@ void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
149void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len, 180void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len,
150 struct xfs_bmap_free *flist, struct xfs_mount *mp); 181 struct xfs_bmap_free *flist, struct xfs_mount *mp);
151void xfs_bmap_cancel(struct xfs_bmap_free *flist); 182void xfs_bmap_cancel(struct xfs_bmap_free *flist);
183int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist,
184 int *committed);
152void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); 185void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
153int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, 186int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
154 xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); 187 xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index fbd6da263571..8eb718979383 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -151,10 +151,13 @@ typedef struct xfs_sb {
151 __uint32_t sb_features2; /* additional feature bits */ 151 __uint32_t sb_features2; /* additional feature bits */
152 152
153 /* 153 /*
154 * bad features2 field as a result of failing to pad the sb 154 * bad features2 field as a result of failing to pad the sb structure to
155 * structure to 64 bits. Some machines will be using this field 155 * 64 bits. Some machines will be using this field for features2 bits.
156 * for features2 bits. Easiest just to mark it bad and not use 156 * Easiest just to mark it bad and not use it for anything else.
157 * it for anything else. 157 *
158 * This is not kept up to date in memory; it is always overwritten by
159 * the value in sb_features2 when formatting the incore superblock to
160 * the disk buffer.
158 */ 161 */
159 __uint32_t sb_bad_features2; 162 __uint32_t sb_bad_features2;
160 163
@@ -304,8 +307,8 @@ typedef enum {
304#define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) 307#define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT)
305#define XFS_SB_IFREE XFS_SB_MVAL(IFREE) 308#define XFS_SB_IFREE XFS_SB_MVAL(IFREE)
306#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) 309#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS)
307#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) 310#define XFS_SB_FEATURES2 (XFS_SB_MVAL(FEATURES2) | \
308#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) 311 XFS_SB_MVAL(BAD_FEATURES2))
309#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) 312#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT)
310#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) 313#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT)
311#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) 314#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT)
@@ -319,9 +322,9 @@ typedef enum {
319 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ 322 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
320 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ 323 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
321 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ 324 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \
322 XFS_SB_BAD_FEATURES2 | XFS_SB_FEATURES_COMPAT | \ 325 XFS_SB_FEATURES_COMPAT | XFS_SB_FEATURES_RO_COMPAT | \
323 XFS_SB_FEATURES_RO_COMPAT | XFS_SB_FEATURES_INCOMPAT | \ 326 XFS_SB_FEATURES_INCOMPAT | XFS_SB_FEATURES_LOG_INCOMPAT | \
324 XFS_SB_FEATURES_LOG_INCOMPAT | XFS_SB_PQUOTINO) 327 XFS_SB_PQUOTINO)
325 328
326 329
327/* 330/*
@@ -453,13 +456,11 @@ static inline void xfs_sb_version_addattr2(struct xfs_sb *sbp)
453{ 456{
454 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; 457 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
455 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT; 458 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
456 sbp->sb_bad_features2 |= XFS_SB_VERSION2_ATTR2BIT;
457} 459}
458 460
459static inline void xfs_sb_version_removeattr2(struct xfs_sb *sbp) 461static inline void xfs_sb_version_removeattr2(struct xfs_sb *sbp)
460{ 462{
461 sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT; 463 sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT;
462 sbp->sb_bad_features2 &= ~XFS_SB_VERSION2_ATTR2BIT;
463 if (!sbp->sb_features2) 464 if (!sbp->sb_features2)
464 sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; 465 sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
465} 466}
@@ -475,7 +476,6 @@ static inline void xfs_sb_version_addprojid32bit(struct xfs_sb *sbp)
475{ 476{
476 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; 477 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
477 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT; 478 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
478 sbp->sb_bad_features2 |= XFS_SB_VERSION2_PROJID32BIT;
479} 479}
480 480
481/* 481/*
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 18dc721ca19f..18dc721ca19f 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 752915fa775a..b0a5fe95a3e2 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -40,69 +40,6 @@
40 * Physical superblock buffer manipulations. Shared with libxfs in userspace. 40 * Physical superblock buffer manipulations. Shared with libxfs in userspace.
41 */ 41 */
42 42
43static const struct {
44 short offset;
45 short type; /* 0 = integer
46 * 1 = binary / string (no translation)
47 */
48} xfs_sb_info[] = {
49 { offsetof(xfs_sb_t, sb_magicnum), 0 },
50 { offsetof(xfs_sb_t, sb_blocksize), 0 },
51 { offsetof(xfs_sb_t, sb_dblocks), 0 },
52 { offsetof(xfs_sb_t, sb_rblocks), 0 },
53 { offsetof(xfs_sb_t, sb_rextents), 0 },
54 { offsetof(xfs_sb_t, sb_uuid), 1 },
55 { offsetof(xfs_sb_t, sb_logstart), 0 },
56 { offsetof(xfs_sb_t, sb_rootino), 0 },
57 { offsetof(xfs_sb_t, sb_rbmino), 0 },
58 { offsetof(xfs_sb_t, sb_rsumino), 0 },
59 { offsetof(xfs_sb_t, sb_rextsize), 0 },
60 { offsetof(xfs_sb_t, sb_agblocks), 0 },
61 { offsetof(xfs_sb_t, sb_agcount), 0 },
62 { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
63 { offsetof(xfs_sb_t, sb_logblocks), 0 },
64 { offsetof(xfs_sb_t, sb_versionnum), 0 },
65 { offsetof(xfs_sb_t, sb_sectsize), 0 },
66 { offsetof(xfs_sb_t, sb_inodesize), 0 },
67 { offsetof(xfs_sb_t, sb_inopblock), 0 },
68 { offsetof(xfs_sb_t, sb_fname[0]), 1 },
69 { offsetof(xfs_sb_t, sb_blocklog), 0 },
70 { offsetof(xfs_sb_t, sb_sectlog), 0 },
71 { offsetof(xfs_sb_t, sb_inodelog), 0 },
72 { offsetof(xfs_sb_t, sb_inopblog), 0 },
73 { offsetof(xfs_sb_t, sb_agblklog), 0 },
74 { offsetof(xfs_sb_t, sb_rextslog), 0 },
75 { offsetof(xfs_sb_t, sb_inprogress), 0 },
76 { offsetof(xfs_sb_t, sb_imax_pct), 0 },
77 { offsetof(xfs_sb_t, sb_icount), 0 },
78 { offsetof(xfs_sb_t, sb_ifree), 0 },
79 { offsetof(xfs_sb_t, sb_fdblocks), 0 },
80 { offsetof(xfs_sb_t, sb_frextents), 0 },
81 { offsetof(xfs_sb_t, sb_uquotino), 0 },
82 { offsetof(xfs_sb_t, sb_gquotino), 0 },
83 { offsetof(xfs_sb_t, sb_qflags), 0 },
84 { offsetof(xfs_sb_t, sb_flags), 0 },
85 { offsetof(xfs_sb_t, sb_shared_vn), 0 },
86 { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
87 { offsetof(xfs_sb_t, sb_unit), 0 },
88 { offsetof(xfs_sb_t, sb_width), 0 },
89 { offsetof(xfs_sb_t, sb_dirblklog), 0 },
90 { offsetof(xfs_sb_t, sb_logsectlog), 0 },
91 { offsetof(xfs_sb_t, sb_logsectsize), 0 },
92 { offsetof(xfs_sb_t, sb_logsunit), 0 },
93 { offsetof(xfs_sb_t, sb_features2), 0 },
94 { offsetof(xfs_sb_t, sb_bad_features2), 0 },
95 { offsetof(xfs_sb_t, sb_features_compat), 0 },
96 { offsetof(xfs_sb_t, sb_features_ro_compat), 0 },
97 { offsetof(xfs_sb_t, sb_features_incompat), 0 },
98 { offsetof(xfs_sb_t, sb_features_log_incompat), 0 },
99 { offsetof(xfs_sb_t, sb_crc), 0 },
100 { offsetof(xfs_sb_t, sb_pad), 0 },
101 { offsetof(xfs_sb_t, sb_pquotino), 0 },
102 { offsetof(xfs_sb_t, sb_lsn), 0 },
103 { sizeof(xfs_sb_t), 0 }
104};
105
106/* 43/*
107 * Reference counting access wrappers to the perag structures. 44 * Reference counting access wrappers to the perag structures.
108 * Because we never free per-ag structures, the only thing we 45 * Because we never free per-ag structures, the only thing we
@@ -461,58 +398,49 @@ xfs_sb_from_disk(
461 __xfs_sb_from_disk(to, from, true); 398 __xfs_sb_from_disk(to, from, true);
462} 399}
463 400
464static inline void 401static void
465xfs_sb_quota_to_disk( 402xfs_sb_quota_to_disk(
466 xfs_dsb_t *to, 403 struct xfs_dsb *to,
467 xfs_sb_t *from, 404 struct xfs_sb *from)
468 __int64_t *fields)
469{ 405{
470 __uint16_t qflags = from->sb_qflags; 406 __uint16_t qflags = from->sb_qflags;
471 407
408 to->sb_uquotino = cpu_to_be64(from->sb_uquotino);
409 if (xfs_sb_version_has_pquotino(from)) {
410 to->sb_qflags = cpu_to_be16(from->sb_qflags);
411 to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
412 to->sb_pquotino = cpu_to_be64(from->sb_pquotino);
413 return;
414 }
415
472 /* 416 /*
473 * We need to do these manipilations only if we are working 417 * The in-core version of sb_qflags do not have XFS_OQUOTA_*
474 * with an older version of on-disk superblock. 418 * flags, whereas the on-disk version does. So, convert incore
419 * XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
475 */ 420 */
476 if (xfs_sb_version_has_pquotino(from)) 421 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
477 return; 422 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
478 423
479 if (*fields & XFS_SB_QFLAGS) { 424 if (from->sb_qflags &
480 /* 425 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
481 * The in-core version of sb_qflags do not have 426 qflags |= XFS_OQUOTA_ENFD;
482 * XFS_OQUOTA_* flags, whereas the on-disk version 427 if (from->sb_qflags &
483 * does. So, convert incore XFS_{PG}QUOTA_* flags 428 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
484 * to on-disk XFS_OQUOTA_* flags. 429 qflags |= XFS_OQUOTA_CHKD;
485 */ 430 to->sb_qflags = cpu_to_be16(qflags);
486 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
487 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
488
489 if (from->sb_qflags &
490 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
491 qflags |= XFS_OQUOTA_ENFD;
492 if (from->sb_qflags &
493 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
494 qflags |= XFS_OQUOTA_CHKD;
495 to->sb_qflags = cpu_to_be16(qflags);
496 *fields &= ~XFS_SB_QFLAGS;
497 }
498 431
499 /* 432 /*
500 * GQUOTINO and PQUOTINO cannot be used together in versions of 433 * GQUOTINO and PQUOTINO cannot be used together in versions
501 * superblock that do not have pquotino. from->sb_flags tells us which 434 * of superblock that do not have pquotino. from->sb_flags
502 * quota is active and should be copied to disk. If neither are active, 435 * tells us which quota is active and should be copied to
503 * make sure we write NULLFSINO to the sb_gquotino field as a quota 436 * disk. If neither are active, we should NULL the inode.
504 * inode value of "0" is invalid when the XFS_SB_VERSION_QUOTA feature
505 * bit is set.
506 * 437 *
507 * Note that we don't need to handle the sb_uquotino or sb_pquotino here 438 * In all cases, the separate pquotino must remain 0 because it
508 * as they do not require any translation. Hence the main sb field loop 439 * it beyond the "end" of the valid non-pquotino superblock.
509 * will write them appropriately from the in-core superblock.
510 */ 440 */
511 if ((*fields & XFS_SB_GQUOTINO) && 441 if (from->sb_qflags & XFS_GQUOTA_ACCT)
512 (from->sb_qflags & XFS_GQUOTA_ACCT))
513 to->sb_gquotino = cpu_to_be64(from->sb_gquotino); 442 to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
514 else if ((*fields & XFS_SB_PQUOTINO) && 443 else if (from->sb_qflags & XFS_PQUOTA_ACCT)
515 (from->sb_qflags & XFS_PQUOTA_ACCT))
516 to->sb_gquotino = cpu_to_be64(from->sb_pquotino); 444 to->sb_gquotino = cpu_to_be64(from->sb_pquotino);
517 else { 445 else {
518 /* 446 /*
@@ -526,63 +454,78 @@ xfs_sb_quota_to_disk(
526 to->sb_gquotino = cpu_to_be64(NULLFSINO); 454 to->sb_gquotino = cpu_to_be64(NULLFSINO);
527 } 455 }
528 456
529 *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); 457 to->sb_pquotino = 0;
530} 458}
531 459
532/*
533 * Copy in core superblock to ondisk one.
534 *
535 * The fields argument is mask of superblock fields to copy.
536 */
537void 460void
538xfs_sb_to_disk( 461xfs_sb_to_disk(
539 xfs_dsb_t *to, 462 struct xfs_dsb *to,
540 xfs_sb_t *from, 463 struct xfs_sb *from)
541 __int64_t fields)
542{ 464{
543 xfs_caddr_t to_ptr = (xfs_caddr_t)to; 465 xfs_sb_quota_to_disk(to, from);
544 xfs_caddr_t from_ptr = (xfs_caddr_t)from;
545 xfs_sb_field_t f;
546 int first;
547 int size;
548
549 ASSERT(fields);
550 if (!fields)
551 return;
552 466
553 /* We should never write the crc here, it's updated in the IO path */ 467 to->sb_magicnum = cpu_to_be32(from->sb_magicnum);
554 fields &= ~XFS_SB_CRC; 468 to->sb_blocksize = cpu_to_be32(from->sb_blocksize);
555 469 to->sb_dblocks = cpu_to_be64(from->sb_dblocks);
556 xfs_sb_quota_to_disk(to, from, &fields); 470 to->sb_rblocks = cpu_to_be64(from->sb_rblocks);
557 while (fields) { 471 to->sb_rextents = cpu_to_be64(from->sb_rextents);
558 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 472 memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
559 first = xfs_sb_info[f].offset; 473 to->sb_logstart = cpu_to_be64(from->sb_logstart);
560 size = xfs_sb_info[f + 1].offset - first; 474 to->sb_rootino = cpu_to_be64(from->sb_rootino);
561 475 to->sb_rbmino = cpu_to_be64(from->sb_rbmino);
562 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); 476 to->sb_rsumino = cpu_to_be64(from->sb_rsumino);
563 477 to->sb_rextsize = cpu_to_be32(from->sb_rextsize);
564 if (size == 1 || xfs_sb_info[f].type == 1) { 478 to->sb_agblocks = cpu_to_be32(from->sb_agblocks);
565 memcpy(to_ptr + first, from_ptr + first, size); 479 to->sb_agcount = cpu_to_be32(from->sb_agcount);
566 } else { 480 to->sb_rbmblocks = cpu_to_be32(from->sb_rbmblocks);
567 switch (size) { 481 to->sb_logblocks = cpu_to_be32(from->sb_logblocks);
568 case 2: 482 to->sb_versionnum = cpu_to_be16(from->sb_versionnum);
569 *(__be16 *)(to_ptr + first) = 483 to->sb_sectsize = cpu_to_be16(from->sb_sectsize);
570 cpu_to_be16(*(__u16 *)(from_ptr + first)); 484 to->sb_inodesize = cpu_to_be16(from->sb_inodesize);
571 break; 485 to->sb_inopblock = cpu_to_be16(from->sb_inopblock);
572 case 4: 486 memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
573 *(__be32 *)(to_ptr + first) = 487 to->sb_blocklog = from->sb_blocklog;
574 cpu_to_be32(*(__u32 *)(from_ptr + first)); 488 to->sb_sectlog = from->sb_sectlog;
575 break; 489 to->sb_inodelog = from->sb_inodelog;
576 case 8: 490 to->sb_inopblog = from->sb_inopblog;
577 *(__be64 *)(to_ptr + first) = 491 to->sb_agblklog = from->sb_agblklog;
578 cpu_to_be64(*(__u64 *)(from_ptr + first)); 492 to->sb_rextslog = from->sb_rextslog;
579 break; 493 to->sb_inprogress = from->sb_inprogress;
580 default: 494 to->sb_imax_pct = from->sb_imax_pct;
581 ASSERT(0); 495 to->sb_icount = cpu_to_be64(from->sb_icount);
582 } 496 to->sb_ifree = cpu_to_be64(from->sb_ifree);
583 } 497 to->sb_fdblocks = cpu_to_be64(from->sb_fdblocks);
498 to->sb_frextents = cpu_to_be64(from->sb_frextents);
584 499
585 fields &= ~(1LL << f); 500 to->sb_flags = from->sb_flags;
501 to->sb_shared_vn = from->sb_shared_vn;
502 to->sb_inoalignmt = cpu_to_be32(from->sb_inoalignmt);
503 to->sb_unit = cpu_to_be32(from->sb_unit);
504 to->sb_width = cpu_to_be32(from->sb_width);
505 to->sb_dirblklog = from->sb_dirblklog;
506 to->sb_logsectlog = from->sb_logsectlog;
507 to->sb_logsectsize = cpu_to_be16(from->sb_logsectsize);
508 to->sb_logsunit = cpu_to_be32(from->sb_logsunit);
509
510 /*
511 * We need to ensure that bad_features2 always matches features2.
512 * Hence we enforce that here rather than having to remember to do it
513 * everywhere else that updates features2.
514 */
515 from->sb_bad_features2 = from->sb_features2;
516 to->sb_features2 = cpu_to_be32(from->sb_features2);
517 to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2);
518
519 if (xfs_sb_version_hascrc(from)) {
520 to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
521 to->sb_features_ro_compat =
522 cpu_to_be32(from->sb_features_ro_compat);
523 to->sb_features_incompat =
524 cpu_to_be32(from->sb_features_incompat);
525 to->sb_features_log_incompat =
526 cpu_to_be32(from->sb_features_log_incompat);
527 to->sb_pad = 0;
528 to->sb_lsn = cpu_to_be64(from->sb_lsn);
586 } 529 }
587} 530}
588 531
@@ -816,42 +759,51 @@ xfs_initialize_perag_data(
816} 759}
817 760
818/* 761/*
819 * xfs_mod_sb() can be used to copy arbitrary changes to the 762 * xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock
820 * in-core superblock into the superblock buffer to be logged. 763 * into the superblock buffer to be logged. It does not provide the higher
821 * It does not provide the higher level of locking that is 764 * level of locking that is needed to protect the in-core superblock from
822 * needed to protect the in-core superblock from concurrent 765 * concurrent access.
823 * access.
824 */ 766 */
825void 767void
826xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) 768xfs_log_sb(
769 struct xfs_trans *tp)
827{ 770{
828 xfs_buf_t *bp; 771 struct xfs_mount *mp = tp->t_mountp;
829 int first; 772 struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0);
830 int last;
831 xfs_mount_t *mp;
832 xfs_sb_field_t f;
833
834 ASSERT(fields);
835 if (!fields)
836 return;
837 mp = tp->t_mountp;
838 bp = xfs_trans_getsb(tp, mp, 0);
839 first = sizeof(xfs_sb_t);
840 last = 0;
841
842 /* translate/copy */
843 773
844 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); 774 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
775 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
776 xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb));
777}
845 778
846 /* find modified range */ 779/*
847 f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); 780 * xfs_sync_sb
848 ASSERT((1LL << f) & XFS_SB_MOD_BITS); 781 *
849 last = xfs_sb_info[f + 1].offset - 1; 782 * Sync the superblock to disk.
783 *
784 * Note that the caller is responsible for checking the frozen state of the
785 * filesystem. This procedure uses the non-blocking transaction allocator and
786 * thus will allow modifications to a frozen fs. This is required because this
787 * code can be called during the process of freezing where use of the high-level
788 * allocator would deadlock.
789 */
790int
791xfs_sync_sb(
792 struct xfs_mount *mp,
793 bool wait)
794{
795 struct xfs_trans *tp;
796 int error;
850 797
851 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 798 tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP);
852 ASSERT((1LL << f) & XFS_SB_MOD_BITS); 799 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
853 first = xfs_sb_info[f].offset; 800 if (error) {
801 xfs_trans_cancel(tp, 0);
802 return error;
803 }
854 804
855 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); 805 xfs_log_sb(tp);
856 xfs_trans_log_buf(tp, bp, first, last); 806 if (wait)
807 xfs_trans_set_sync(tp);
808 return xfs_trans_commit(tp, 0);
857} 809}
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 8eb1c54bafbf..b25bb9a343f3 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -27,11 +27,12 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t,
27extern void xfs_perag_put(struct xfs_perag *pag); 27extern void xfs_perag_put(struct xfs_perag *pag);
28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); 28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t);
29 29
30extern void xfs_sb_calc_crc(struct xfs_buf *); 30extern void xfs_sb_calc_crc(struct xfs_buf *bp);
31extern void xfs_mod_sb(struct xfs_trans *, __int64_t); 31extern void xfs_log_sb(struct xfs_trans *tp);
32extern void xfs_sb_mount_common(struct xfs_mount *, struct xfs_sb *); 32extern int xfs_sync_sb(struct xfs_mount *mp, bool wait);
33extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); 33extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
34extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); 34extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
35extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
35extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp); 36extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp);
36 37
37#endif /* __XFS_SB_H__ */ 38#endif /* __XFS_SB_H__ */
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h
index 82404da2ca67..8dda4b321343 100644
--- a/fs/xfs/libxfs/xfs_shared.h
+++ b/fs/xfs/libxfs/xfs_shared.h
@@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
82#define XFS_TRANS_ATTR_RM 23 82#define XFS_TRANS_ATTR_RM 23
83#define XFS_TRANS_ATTR_FLAG 24 83#define XFS_TRANS_ATTR_FLAG 24
84#define XFS_TRANS_CLEAR_AGI_BUCKET 25 84#define XFS_TRANS_CLEAR_AGI_BUCKET 25
85#define XFS_TRANS_QM_SBCHANGE 26 85#define XFS_TRANS_SB_CHANGE 26
86/* 86/*
87 * Dummy entries since we use the transaction type to index into the 87 * Dummy entries since we use the transaction type to index into the
88 * trans_type[] in xlog_recover_print_trans_head() 88 * trans_type[] in xlog_recover_print_trans_head()
@@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
95#define XFS_TRANS_QM_DQCLUSTER 32 95#define XFS_TRANS_QM_DQCLUSTER 32
96#define XFS_TRANS_QM_QINOCREATE 33 96#define XFS_TRANS_QM_QINOCREATE 33
97#define XFS_TRANS_QM_QUOTAOFF_END 34 97#define XFS_TRANS_QM_QUOTAOFF_END 34
98#define XFS_TRANS_SB_UNIT 35 98#define XFS_TRANS_FSYNC_TS 35
99#define XFS_TRANS_FSYNC_TS 36 99#define XFS_TRANS_GROWFSRT_ALLOC 36
100#define XFS_TRANS_GROWFSRT_ALLOC 37 100#define XFS_TRANS_GROWFSRT_ZERO 37
101#define XFS_TRANS_GROWFSRT_ZERO 38 101#define XFS_TRANS_GROWFSRT_FREE 38
102#define XFS_TRANS_GROWFSRT_FREE 39 102#define XFS_TRANS_SWAPEXT 39
103#define XFS_TRANS_SWAPEXT 40 103#define XFS_TRANS_CHECKPOINT 40
104#define XFS_TRANS_SB_COUNT 41 104#define XFS_TRANS_ICREATE 41
105#define XFS_TRANS_CHECKPOINT 42 105#define XFS_TRANS_CREATE_TMPFILE 42
106#define XFS_TRANS_ICREATE 43 106#define XFS_TRANS_TYPE_MAX 43
107#define XFS_TRANS_CREATE_TMPFILE 44
108#define XFS_TRANS_TYPE_MAX 44
109/* new transaction types need to be reflected in xfs_logprint(8) */ 107/* new transaction types need to be reflected in xfs_logprint(8) */
110 108
111#define XFS_TRANS_TYPES \ 109#define XFS_TRANS_TYPES \
@@ -113,7 +111,6 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
113 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ 111 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
114 { XFS_TRANS_INACTIVE, "INACTIVE" }, \ 112 { XFS_TRANS_INACTIVE, "INACTIVE" }, \
115 { XFS_TRANS_CREATE, "CREATE" }, \ 113 { XFS_TRANS_CREATE, "CREATE" }, \
116 { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \
117 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ 114 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
118 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ 115 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
119 { XFS_TRANS_REMOVE, "REMOVE" }, \ 116 { XFS_TRANS_REMOVE, "REMOVE" }, \
@@ -134,23 +131,23 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
134 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ 131 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \
135 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ 132 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \
136 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ 133 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \
137 { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ 134 { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \
135 { XFS_TRANS_DUMMY1, "DUMMY1" }, \
136 { XFS_TRANS_DUMMY2, "DUMMY2" }, \
138 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ 137 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \
139 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ 138 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \
140 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ 139 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \
141 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ 140 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \
142 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ 141 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \
143 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ 142 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \
144 { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \
145 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ 143 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \
146 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ 144 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \
147 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ 145 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \
148 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ 146 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \
149 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ 147 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \
150 { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \
151 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ 148 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \
152 { XFS_TRANS_DUMMY1, "DUMMY1" }, \ 149 { XFS_TRANS_ICREATE, "ICREATE" }, \
153 { XFS_TRANS_DUMMY2, "DUMMY2" }, \ 150 { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \
154 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } 151 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" }
155 152
156/* 153/*
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c
index c80c5236c3da..e7e26bd6468f 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.c
+++ b/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -178,6 +178,8 @@ xfs_symlink_local_to_remote(
178 struct xfs_mount *mp = ip->i_mount; 178 struct xfs_mount *mp = ip->i_mount;
179 char *buf; 179 char *buf;
180 180
181 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
182
181 if (!xfs_sb_version_hascrc(&mp->m_sb)) { 183 if (!xfs_sb_version_hascrc(&mp->m_sb)) {
182 bp->b_ops = NULL; 184 bp->b_ops = NULL;
183 memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); 185 memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index 6c1330f29050..68cb1e7bf2bb 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -716,17 +716,6 @@ xfs_calc_clear_agi_bucket_reservation(
716} 716}
717 717
718/* 718/*
719 * Clearing the quotaflags in the superblock.
720 * the super block for changing quota flags: sector size
721 */
722STATIC uint
723xfs_calc_qm_sbchange_reservation(
724 struct xfs_mount *mp)
725{
726 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
727}
728
729/*
730 * Adjusting quota limits. 719 * Adjusting quota limits.
731 * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) 720 * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot)
732 */ 721 */
@@ -864,9 +853,6 @@ xfs_trans_resv_calc(
864 * The following transactions are logged in logical format with 853 * The following transactions are logged in logical format with
865 * a default log count. 854 * a default log count.
866 */ 855 */
867 resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp);
868 resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT;
869
870 resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp); 856 resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp);
871 resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; 857 resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT;
872 858
diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h
index 1097d14cd583..2d5bdfce6d8f 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.h
+++ b/fs/xfs/libxfs/xfs_trans_resv.h
@@ -56,7 +56,6 @@ struct xfs_trans_resv {
56 struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */ 56 struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */
57 struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */ 57 struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */
58 struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ 58 struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */
59 struct xfs_trans_res tr_qm_sbchange; /* change quota flags */
60 struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ 59 struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */
61 struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ 60 struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */
62 struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ 61 struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index b79dc66b2ecd..b79dc66b2ecd 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 18e2f3bbae5e..3a9b7a1b8704 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -135,30 +135,22 @@ xfs_setfilesize_trans_alloc(
135 */ 135 */
136STATIC int 136STATIC int
137xfs_setfilesize( 137xfs_setfilesize(
138 struct xfs_ioend *ioend) 138 struct xfs_inode *ip,
139 struct xfs_trans *tp,
140 xfs_off_t offset,
141 size_t size)
139{ 142{
140 struct xfs_inode *ip = XFS_I(ioend->io_inode);
141 struct xfs_trans *tp = ioend->io_append_trans;
142 xfs_fsize_t isize; 143 xfs_fsize_t isize;
143 144
144 /*
145 * The transaction may have been allocated in the I/O submission thread,
146 * thus we need to mark ourselves as beeing in a transaction manually.
147 * Similarly for freeze protection.
148 */
149 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
150 rwsem_acquire_read(&VFS_I(ip)->i_sb->s_writers.lock_map[SB_FREEZE_FS-1],
151 0, 1, _THIS_IP_);
152
153 xfs_ilock(ip, XFS_ILOCK_EXCL); 145 xfs_ilock(ip, XFS_ILOCK_EXCL);
154 isize = xfs_new_eof(ip, ioend->io_offset + ioend->io_size); 146 isize = xfs_new_eof(ip, offset + size);
155 if (!isize) { 147 if (!isize) {
156 xfs_iunlock(ip, XFS_ILOCK_EXCL); 148 xfs_iunlock(ip, XFS_ILOCK_EXCL);
157 xfs_trans_cancel(tp, 0); 149 xfs_trans_cancel(tp, 0);
158 return 0; 150 return 0;
159 } 151 }
160 152
161 trace_xfs_setfilesize(ip, ioend->io_offset, ioend->io_size); 153 trace_xfs_setfilesize(ip, offset, size);
162 154
163 ip->i_d.di_size = isize; 155 ip->i_d.di_size = isize;
164 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 156 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -167,6 +159,25 @@ xfs_setfilesize(
167 return xfs_trans_commit(tp, 0); 159 return xfs_trans_commit(tp, 0);
168} 160}
169 161
162STATIC int
163xfs_setfilesize_ioend(
164 struct xfs_ioend *ioend)
165{
166 struct xfs_inode *ip = XFS_I(ioend->io_inode);
167 struct xfs_trans *tp = ioend->io_append_trans;
168
169 /*
170 * The transaction may have been allocated in the I/O submission thread,
171 * thus we need to mark ourselves as being in a transaction manually.
172 * Similarly for freeze protection.
173 */
174 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
175 rwsem_acquire_read(&VFS_I(ip)->i_sb->s_writers.lock_map[SB_FREEZE_FS-1],
176 0, 1, _THIS_IP_);
177
178 return xfs_setfilesize(ip, tp, ioend->io_offset, ioend->io_size);
179}
180
170/* 181/*
171 * Schedule IO completion handling on the final put of an ioend. 182 * Schedule IO completion handling on the final put of an ioend.
172 * 183 *
@@ -182,8 +193,7 @@ xfs_finish_ioend(
182 193
183 if (ioend->io_type == XFS_IO_UNWRITTEN) 194 if (ioend->io_type == XFS_IO_UNWRITTEN)
184 queue_work(mp->m_unwritten_workqueue, &ioend->io_work); 195 queue_work(mp->m_unwritten_workqueue, &ioend->io_work);
185 else if (ioend->io_append_trans || 196 else if (ioend->io_append_trans)
186 (ioend->io_isdirect && xfs_ioend_is_append(ioend)))
187 queue_work(mp->m_data_workqueue, &ioend->io_work); 197 queue_work(mp->m_data_workqueue, &ioend->io_work);
188 else 198 else
189 xfs_destroy_ioend(ioend); 199 xfs_destroy_ioend(ioend);
@@ -215,22 +225,8 @@ xfs_end_io(
215 if (ioend->io_type == XFS_IO_UNWRITTEN) { 225 if (ioend->io_type == XFS_IO_UNWRITTEN) {
216 error = xfs_iomap_write_unwritten(ip, ioend->io_offset, 226 error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
217 ioend->io_size); 227 ioend->io_size);
218 } else if (ioend->io_isdirect && xfs_ioend_is_append(ioend)) {
219 /*
220 * For direct I/O we do not know if we need to allocate blocks
221 * or not so we can't preallocate an append transaction as that
222 * results in nested reservations and log space deadlocks. Hence
223 * allocate the transaction here. While this is sub-optimal and
224 * can block IO completion for some time, we're stuck with doing
225 * it this way until we can pass the ioend to the direct IO
226 * allocation callbacks and avoid nesting that way.
227 */
228 error = xfs_setfilesize_trans_alloc(ioend);
229 if (error)
230 goto done;
231 error = xfs_setfilesize(ioend);
232 } else if (ioend->io_append_trans) { 228 } else if (ioend->io_append_trans) {
233 error = xfs_setfilesize(ioend); 229 error = xfs_setfilesize_ioend(ioend);
234 } else { 230 } else {
235 ASSERT(!xfs_ioend_is_append(ioend)); 231 ASSERT(!xfs_ioend_is_append(ioend));
236 } 232 }
@@ -242,17 +238,6 @@ done:
242} 238}
243 239
244/* 240/*
245 * Call IO completion handling in caller context on the final put of an ioend.
246 */
247STATIC void
248xfs_finish_ioend_sync(
249 struct xfs_ioend *ioend)
250{
251 if (atomic_dec_and_test(&ioend->io_remaining))
252 xfs_end_io(&ioend->io_work);
253}
254
255/*
256 * Allocate and initialise an IO completion structure. 241 * Allocate and initialise an IO completion structure.
257 * We need to track unwritten extent write completion here initially. 242 * We need to track unwritten extent write completion here initially.
258 * We'll need to extend this for updating the ondisk inode size later 243 * We'll need to extend this for updating the ondisk inode size later
@@ -273,7 +258,6 @@ xfs_alloc_ioend(
273 * all the I/O from calling the completion routine too early. 258 * all the I/O from calling the completion routine too early.
274 */ 259 */
275 atomic_set(&ioend->io_remaining, 1); 260 atomic_set(&ioend->io_remaining, 1);
276 ioend->io_isdirect = 0;
277 ioend->io_error = 0; 261 ioend->io_error = 0;
278 ioend->io_list = NULL; 262 ioend->io_list = NULL;
279 ioend->io_type = type; 263 ioend->io_type = type;
@@ -1459,11 +1443,7 @@ xfs_get_blocks_direct(
1459 * 1443 *
1460 * If the private argument is non-NULL __xfs_get_blocks signals us that we 1444 * If the private argument is non-NULL __xfs_get_blocks signals us that we
1461 * need to issue a transaction to convert the range from unwritten to written 1445 * need to issue a transaction to convert the range from unwritten to written
1462 * extents. In case this is regular synchronous I/O we just call xfs_end_io 1446 * extents.
1463 * to do this and we are done. But in case this was a successful AIO
1464 * request this handler is called from interrupt context, from which we
1465 * can't start transactions. In that case offload the I/O completion to
1466 * the workqueues we also use for buffered I/O completion.
1467 */ 1447 */
1468STATIC void 1448STATIC void
1469xfs_end_io_direct_write( 1449xfs_end_io_direct_write(
@@ -1472,7 +1452,12 @@ xfs_end_io_direct_write(
1472 ssize_t size, 1452 ssize_t size,
1473 void *private) 1453 void *private)
1474{ 1454{
1475 struct xfs_ioend *ioend = iocb->private; 1455 struct inode *inode = file_inode(iocb->ki_filp);
1456 struct xfs_inode *ip = XFS_I(inode);
1457 struct xfs_mount *mp = ip->i_mount;
1458
1459 if (XFS_FORCED_SHUTDOWN(mp))
1460 return;
1476 1461
1477 /* 1462 /*
1478 * While the generic direct I/O code updates the inode size, it does 1463 * While the generic direct I/O code updates the inode size, it does
@@ -1480,22 +1465,33 @@ xfs_end_io_direct_write(
1480 * end_io handler thinks the on-disk size is outside the in-core 1465 * end_io handler thinks the on-disk size is outside the in-core
1481 * size. To prevent this just update it a little bit earlier here. 1466 * size. To prevent this just update it a little bit earlier here.
1482 */ 1467 */
1483 if (offset + size > i_size_read(ioend->io_inode)) 1468 if (offset + size > i_size_read(inode))
1484 i_size_write(ioend->io_inode, offset + size); 1469 i_size_write(inode, offset + size);
1485 1470
1486 /* 1471 /*
1487 * blockdev_direct_IO can return an error even after the I/O 1472 * For direct I/O we do not know if we need to allocate blocks or not,
1488 * completion handler was called. Thus we need to protect 1473 * so we can't preallocate an append transaction, as that results in
1489 * against double-freeing. 1474 * nested reservations and log space deadlocks. Hence allocate the
1475 * transaction here. While this is sub-optimal and can block IO
1476 * completion for some time, we're stuck with doing it this way until
1477 * we can pass the ioend to the direct IO allocation callbacks and
1478 * avoid nesting that way.
1490 */ 1479 */
1491 iocb->private = NULL; 1480 if (private && size > 0) {
1492 1481 xfs_iomap_write_unwritten(ip, offset, size);
1493 ioend->io_offset = offset; 1482 } else if (offset + size > ip->i_d.di_size) {
1494 ioend->io_size = size; 1483 struct xfs_trans *tp;
1495 if (private && size > 0) 1484 int error;
1496 ioend->io_type = XFS_IO_UNWRITTEN; 1485
1486 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
1487 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
1488 if (error) {
1489 xfs_trans_cancel(tp, 0);
1490 return;
1491 }
1497 1492
1498 xfs_finish_ioend_sync(ioend); 1493 xfs_setfilesize(ip, tp, offset, size);
1494 }
1499} 1495}
1500 1496
1501STATIC ssize_t 1497STATIC ssize_t
@@ -1507,39 +1503,16 @@ xfs_vm_direct_IO(
1507{ 1503{
1508 struct inode *inode = iocb->ki_filp->f_mapping->host; 1504 struct inode *inode = iocb->ki_filp->f_mapping->host;
1509 struct block_device *bdev = xfs_find_bdev_for_inode(inode); 1505 struct block_device *bdev = xfs_find_bdev_for_inode(inode);
1510 struct xfs_ioend *ioend = NULL;
1511 ssize_t ret;
1512 1506
1513 if (rw & WRITE) { 1507 if (rw & WRITE) {
1514 size_t size = iov_iter_count(iter); 1508 return __blockdev_direct_IO(rw, iocb, inode, bdev, iter,
1515
1516 /*
1517 * We cannot preallocate a size update transaction here as we
1518 * don't know whether allocation is necessary or not. Hence we
1519 * can only tell IO completion that one is necessary if we are
1520 * not doing unwritten extent conversion.
1521 */
1522 iocb->private = ioend = xfs_alloc_ioend(inode, XFS_IO_DIRECT);
1523 if (offset + size > XFS_I(inode)->i_d.di_size)
1524 ioend->io_isdirect = 1;
1525
1526 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iter,
1527 offset, xfs_get_blocks_direct, 1509 offset, xfs_get_blocks_direct,
1528 xfs_end_io_direct_write, NULL, 1510 xfs_end_io_direct_write, NULL,
1529 DIO_ASYNC_EXTEND); 1511 DIO_ASYNC_EXTEND);
1530 if (ret != -EIOCBQUEUED && iocb->private)
1531 goto out_destroy_ioend;
1532 } else {
1533 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iter,
1534 offset, xfs_get_blocks_direct,
1535 NULL, NULL, 0);
1536 } 1512 }
1537 1513 return __blockdev_direct_IO(rw, iocb, inode, bdev, iter,
1538 return ret; 1514 offset, xfs_get_blocks_direct,
1539 1515 NULL, NULL, 0);
1540out_destroy_ioend:
1541 xfs_destroy_ioend(ioend);
1542 return ret;
1543} 1516}
1544 1517
1545/* 1518/*
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index f94dd459dff9..ac644e0137a4 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -24,14 +24,12 @@ extern mempool_t *xfs_ioend_pool;
24 * Types of I/O for bmap clustering and I/O completion tracking. 24 * Types of I/O for bmap clustering and I/O completion tracking.
25 */ 25 */
26enum { 26enum {
27 XFS_IO_DIRECT = 0, /* special case for direct I/O ioends */
28 XFS_IO_DELALLOC, /* covers delalloc region */ 27 XFS_IO_DELALLOC, /* covers delalloc region */
29 XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */ 28 XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */
30 XFS_IO_OVERWRITE, /* covers already allocated extent */ 29 XFS_IO_OVERWRITE, /* covers already allocated extent */
31}; 30};
32 31
33#define XFS_IO_TYPES \ 32#define XFS_IO_TYPES \
34 { 0, "" }, \
35 { XFS_IO_DELALLOC, "delalloc" }, \ 33 { XFS_IO_DELALLOC, "delalloc" }, \
36 { XFS_IO_UNWRITTEN, "unwritten" }, \ 34 { XFS_IO_UNWRITTEN, "unwritten" }, \
37 { XFS_IO_OVERWRITE, "overwrite" } 35 { XFS_IO_OVERWRITE, "overwrite" }
@@ -45,7 +43,6 @@ typedef struct xfs_ioend {
45 unsigned int io_type; /* delalloc / unwritten */ 43 unsigned int io_type; /* delalloc / unwritten */
46 int io_error; /* I/O error code */ 44 int io_error; /* I/O error code */
47 atomic_t io_remaining; /* hold count */ 45 atomic_t io_remaining; /* hold count */
48 unsigned int io_isdirect : 1;/* direct I/O */
49 struct inode *io_inode; /* file being written to */ 46 struct inode *io_inode; /* file being written to */
50 struct buffer_head *io_buffer_head;/* buffer linked list head */ 47 struct buffer_head *io_buffer_head;/* buffer linked list head */
51 struct buffer_head *io_buffer_tail;/* buffer linked list tail */ 48 struct buffer_head *io_buffer_tail;/* buffer linked list tail */
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h
index 2fdb72d2c908..736429a72a12 100644
--- a/fs/xfs/xfs_bmap_util.h
+++ b/fs/xfs/xfs_bmap_util.h
@@ -26,43 +26,8 @@ struct xfs_ifork;
26struct xfs_inode; 26struct xfs_inode;
27struct xfs_mount; 27struct xfs_mount;
28struct xfs_trans; 28struct xfs_trans;
29struct xfs_bmalloca;
29 30
30/*
31 * Argument structure for xfs_bmap_alloc.
32 */
33struct xfs_bmalloca {
34 xfs_fsblock_t *firstblock; /* i/o first block allocated */
35 struct xfs_bmap_free *flist; /* bmap freelist */
36 struct xfs_trans *tp; /* transaction pointer */
37 struct xfs_inode *ip; /* incore inode pointer */
38 struct xfs_bmbt_irec prev; /* extent before the new one */
39 struct xfs_bmbt_irec got; /* extent after, or delayed */
40
41 xfs_fileoff_t offset; /* offset in file filling in */
42 xfs_extlen_t length; /* i/o length asked/allocated */
43 xfs_fsblock_t blkno; /* starting block of new extent */
44
45 struct xfs_btree_cur *cur; /* btree cursor */
46 xfs_extnum_t idx; /* current extent index */
47 int nallocs;/* number of extents alloc'd */
48 int logflags;/* flags for transaction logging */
49
50 xfs_extlen_t total; /* total blocks needed for xaction */
51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */
52 xfs_extlen_t minleft; /* amount must be left after alloc */
53 bool eof; /* set if allocating past last extent */
54 bool wasdel; /* replacing a delayed allocation */
55 bool userdata;/* set if is user data */
56 bool aeof; /* allocated space at eof */
57 bool conv; /* overwriting unwritten extents */
58 int flags;
59 struct completion *done;
60 struct work_struct work;
61 int result;
62};
63
64int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist,
65 int *committed);
66int xfs_bmap_rtalloc(struct xfs_bmalloca *ap); 31int xfs_bmap_rtalloc(struct xfs_bmalloca *ap);
67int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff, 32int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff,
68 int whichfork, int *eof); 33 int whichfork, int *eof);
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 3f9bd58edec7..507d96a57ac7 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -319,6 +319,10 @@ xfs_buf_item_format(
319 ASSERT(atomic_read(&bip->bli_refcount) > 0); 319 ASSERT(atomic_read(&bip->bli_refcount) > 0);
320 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || 320 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
321 (bip->bli_flags & XFS_BLI_STALE)); 321 (bip->bli_flags & XFS_BLI_STALE));
322 ASSERT((bip->bli_flags & XFS_BLI_STALE) ||
323 (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF
324 && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF));
325
322 326
323 /* 327 /*
324 * If it is an inode buffer, transfer the in-memory state to the 328 * If it is an inode buffer, transfer the in-memory state to the
@@ -535,7 +539,7 @@ xfs_buf_item_push(
535 if ((bp->b_flags & XBF_WRITE_FAIL) && 539 if ((bp->b_flags & XBF_WRITE_FAIL) &&
536 ___ratelimit(&xfs_buf_write_fail_rl_state, "XFS:")) { 540 ___ratelimit(&xfs_buf_write_fail_rl_state, "XFS:")) {
537 xfs_warn(bp->b_target->bt_mount, 541 xfs_warn(bp->b_target->bt_mount,
538"Detected failing async write on buffer block 0x%llx. Retrying async write.\n", 542"Detected failing async write on buffer block 0x%llx. Retrying async write.",
539 (long long)bp->b_bn); 543 (long long)bp->b_bn);
540 } 544 }
541 545
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index c24c67e22a2a..2f536f33cd26 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -86,7 +86,7 @@ static inline void xfs_dqflock(xfs_dquot_t *dqp)
86 wait_for_completion(&dqp->q_flush); 86 wait_for_completion(&dqp->q_flush);
87} 87}
88 88
89static inline int xfs_dqflock_nowait(xfs_dquot_t *dqp) 89static inline bool xfs_dqflock_nowait(xfs_dquot_t *dqp)
90{ 90{
91 return try_wait_for_completion(&dqp->q_flush); 91 return try_wait_for_completion(&dqp->q_flush);
92} 92}
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 13e974e6a889..712d312d8e3e 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -127,6 +127,42 @@ xfs_iozero(
127 return (-status); 127 return (-status);
128} 128}
129 129
130int
131xfs_update_prealloc_flags(
132 struct xfs_inode *ip,
133 enum xfs_prealloc_flags flags)
134{
135 struct xfs_trans *tp;
136 int error;
137
138 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
139 error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
140 if (error) {
141 xfs_trans_cancel(tp, 0);
142 return error;
143 }
144
145 xfs_ilock(ip, XFS_ILOCK_EXCL);
146 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
147
148 if (!(flags & XFS_PREALLOC_INVISIBLE)) {
149 ip->i_d.di_mode &= ~S_ISUID;
150 if (ip->i_d.di_mode & S_IXGRP)
151 ip->i_d.di_mode &= ~S_ISGID;
152 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
153 }
154
155 if (flags & XFS_PREALLOC_SET)
156 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
157 if (flags & XFS_PREALLOC_CLEAR)
158 ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
159
160 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
161 if (flags & XFS_PREALLOC_SYNC)
162 xfs_trans_set_sync(tp);
163 return xfs_trans_commit(tp, 0);
164}
165
130/* 166/*
131 * Fsync operations on directories are much simpler than on regular files, 167 * Fsync operations on directories are much simpler than on regular files,
132 * as there is no file data to flush, and thus also no need for explicit 168 * as there is no file data to flush, and thus also no need for explicit
@@ -784,8 +820,8 @@ xfs_file_fallocate(
784{ 820{
785 struct inode *inode = file_inode(file); 821 struct inode *inode = file_inode(file);
786 struct xfs_inode *ip = XFS_I(inode); 822 struct xfs_inode *ip = XFS_I(inode);
787 struct xfs_trans *tp;
788 long error; 823 long error;
824 enum xfs_prealloc_flags flags = 0;
789 loff_t new_size = 0; 825 loff_t new_size = 0;
790 826
791 if (!S_ISREG(inode->i_mode)) 827 if (!S_ISREG(inode->i_mode))
@@ -822,6 +858,8 @@ xfs_file_fallocate(
822 if (error) 858 if (error)
823 goto out_unlock; 859 goto out_unlock;
824 } else { 860 } else {
861 flags |= XFS_PREALLOC_SET;
862
825 if (!(mode & FALLOC_FL_KEEP_SIZE) && 863 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
826 offset + len > i_size_read(inode)) { 864 offset + len > i_size_read(inode)) {
827 new_size = offset + len; 865 new_size = offset + len;
@@ -839,28 +877,10 @@ xfs_file_fallocate(
839 goto out_unlock; 877 goto out_unlock;
840 } 878 }
841 879
842 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
843 error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
844 if (error) {
845 xfs_trans_cancel(tp, 0);
846 goto out_unlock;
847 }
848
849 xfs_ilock(ip, XFS_ILOCK_EXCL);
850 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
851 ip->i_d.di_mode &= ~S_ISUID;
852 if (ip->i_d.di_mode & S_IXGRP)
853 ip->i_d.di_mode &= ~S_ISGID;
854
855 if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)))
856 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
857
858 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
859 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
860
861 if (file->f_flags & O_DSYNC) 880 if (file->f_flags & O_DSYNC)
862 xfs_trans_set_sync(tp); 881 flags |= XFS_PREALLOC_SYNC;
863 error = xfs_trans_commit(tp, 0); 882
883 error = xfs_update_prealloc_flags(ip, flags);
864 if (error) 884 if (error)
865 goto out_unlock; 885 goto out_unlock;
866 886
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index fdc64220fcb0..fba6532efba4 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -488,6 +488,7 @@ xfs_growfs_data_private(
488 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree); 488 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
489 if (dpct) 489 if (dpct)
490 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct); 490 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
491 xfs_trans_set_sync(tp);
491 error = xfs_trans_commit(tp, 0); 492 error = xfs_trans_commit(tp, 0);
492 if (error) 493 if (error)
493 return error; 494 return error;
@@ -541,7 +542,7 @@ xfs_growfs_data_private(
541 saved_error = error; 542 saved_error = error;
542 continue; 543 continue;
543 } 544 }
544 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); 545 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
545 546
546 error = xfs_bwrite(bp); 547 error = xfs_bwrite(bp);
547 xfs_buf_relse(bp); 548 xfs_buf_relse(bp);
@@ -756,37 +757,6 @@ out:
756 return 0; 757 return 0;
757} 758}
758 759
759/*
760 * Dump a transaction into the log that contains no real change. This is needed
761 * to be able to make the log dirty or stamp the current tail LSN into the log
762 * during the covering operation.
763 *
764 * We cannot use an inode here for this - that will push dirty state back up
765 * into the VFS and then periodic inode flushing will prevent log covering from
766 * making progress. Hence we log a field in the superblock instead and use a
767 * synchronous transaction to ensure the superblock is immediately unpinned
768 * and can be written back.
769 */
770int
771xfs_fs_log_dummy(
772 xfs_mount_t *mp)
773{
774 xfs_trans_t *tp;
775 int error;
776
777 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP);
778 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
779 if (error) {
780 xfs_trans_cancel(tp, 0);
781 return error;
782 }
783
784 /* log the UUID because it is an unchanging field */
785 xfs_mod_sb(tp, XFS_SB_UUID);
786 xfs_trans_set_sync(tp);
787 return xfs_trans_commit(tp, 0);
788}
789
790int 760int
791xfs_fs_goingdown( 761xfs_fs_goingdown(
792 xfs_mount_t *mp, 762 xfs_mount_t *mp,
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 41f804e740d7..daafa1f6d260 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1995,6 +1995,7 @@ xfs_iunlink(
1995 agi->agi_unlinked[bucket_index] = cpu_to_be32(agino); 1995 agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
1996 offset = offsetof(xfs_agi_t, agi_unlinked) + 1996 offset = offsetof(xfs_agi_t, agi_unlinked) +
1997 (sizeof(xfs_agino_t) * bucket_index); 1997 (sizeof(xfs_agino_t) * bucket_index);
1998 xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
1998 xfs_trans_log_buf(tp, agibp, offset, 1999 xfs_trans_log_buf(tp, agibp, offset,
1999 (offset + sizeof(xfs_agino_t) - 1)); 2000 (offset + sizeof(xfs_agino_t) - 1));
2000 return 0; 2001 return 0;
@@ -2086,6 +2087,7 @@ xfs_iunlink_remove(
2086 agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino); 2087 agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
2087 offset = offsetof(xfs_agi_t, agi_unlinked) + 2088 offset = offsetof(xfs_agi_t, agi_unlinked) +
2088 (sizeof(xfs_agino_t) * bucket_index); 2089 (sizeof(xfs_agino_t) * bucket_index);
2090 xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
2089 xfs_trans_log_buf(tp, agibp, offset, 2091 xfs_trans_log_buf(tp, agibp, offset,
2090 (offset + sizeof(xfs_agino_t) - 1)); 2092 (offset + sizeof(xfs_agino_t) - 1));
2091 } else { 2093 } else {
@@ -2656,6 +2658,124 @@ xfs_sort_for_rename(
2656} 2658}
2657 2659
2658/* 2660/*
2661 * xfs_cross_rename()
2662 *
2663 * responsible for handling RENAME_EXCHANGE flag in renameat2() sytemcall
2664 */
2665STATIC int
2666xfs_cross_rename(
2667 struct xfs_trans *tp,
2668 struct xfs_inode *dp1,
2669 struct xfs_name *name1,
2670 struct xfs_inode *ip1,
2671 struct xfs_inode *dp2,
2672 struct xfs_name *name2,
2673 struct xfs_inode *ip2,
2674 struct xfs_bmap_free *free_list,
2675 xfs_fsblock_t *first_block,
2676 int spaceres)
2677{
2678 int error = 0;
2679 int ip1_flags = 0;
2680 int ip2_flags = 0;
2681 int dp2_flags = 0;
2682
2683 /* Swap inode number for dirent in first parent */
2684 error = xfs_dir_replace(tp, dp1, name1,
2685 ip2->i_ino,
2686 first_block, free_list, spaceres);
2687 if (error)
2688 goto out;
2689
2690 /* Swap inode number for dirent in second parent */
2691 error = xfs_dir_replace(tp, dp2, name2,
2692 ip1->i_ino,
2693 first_block, free_list, spaceres);
2694 if (error)
2695 goto out;
2696
2697 /*
2698 * If we're renaming one or more directories across different parents,
2699 * update the respective ".." entries (and link counts) to match the new
2700 * parents.
2701 */
2702 if (dp1 != dp2) {
2703 dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
2704
2705 if (S_ISDIR(ip2->i_d.di_mode)) {
2706 error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
2707 dp1->i_ino, first_block,
2708 free_list, spaceres);
2709 if (error)
2710 goto out;
2711
2712 /* transfer ip2 ".." reference to dp1 */
2713 if (!S_ISDIR(ip1->i_d.di_mode)) {
2714 error = xfs_droplink(tp, dp2);
2715 if (error)
2716 goto out;
2717 error = xfs_bumplink(tp, dp1);
2718 if (error)
2719 goto out;
2720 }
2721
2722 /*
2723 * Although ip1 isn't changed here, userspace needs
2724 * to be warned about the change, so that applications
2725 * relying on it (like backup ones), will properly
2726 * notify the change
2727 */
2728 ip1_flags |= XFS_ICHGTIME_CHG;
2729 ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
2730 }
2731
2732 if (S_ISDIR(ip1->i_d.di_mode)) {
2733 error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
2734 dp2->i_ino, first_block,
2735 free_list, spaceres);
2736 if (error)
2737 goto out;
2738
2739 /* transfer ip1 ".." reference to dp2 */
2740 if (!S_ISDIR(ip2->i_d.di_mode)) {
2741 error = xfs_droplink(tp, dp1);
2742 if (error)
2743 goto out;
2744 error = xfs_bumplink(tp, dp2);
2745 if (error)
2746 goto out;
2747 }
2748
2749 /*
2750 * Although ip2 isn't changed here, userspace needs
2751 * to be warned about the change, so that applications
2752 * relying on it (like backup ones), will properly
2753 * notify the change
2754 */
2755 ip1_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
2756 ip2_flags |= XFS_ICHGTIME_CHG;
2757 }
2758 }
2759
2760 if (ip1_flags) {
2761 xfs_trans_ichgtime(tp, ip1, ip1_flags);
2762 xfs_trans_log_inode(tp, ip1, XFS_ILOG_CORE);
2763 }
2764 if (ip2_flags) {
2765 xfs_trans_ichgtime(tp, ip2, ip2_flags);
2766 xfs_trans_log_inode(tp, ip2, XFS_ILOG_CORE);
2767 }
2768 if (dp2_flags) {
2769 xfs_trans_ichgtime(tp, dp2, dp2_flags);
2770 xfs_trans_log_inode(tp, dp2, XFS_ILOG_CORE);
2771 }
2772 xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2773 xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
2774out:
2775 return error;
2776}
2777
2778/*
2659 * xfs_rename 2779 * xfs_rename
2660 */ 2780 */
2661int 2781int
@@ -2665,7 +2785,8 @@ xfs_rename(
2665 xfs_inode_t *src_ip, 2785 xfs_inode_t *src_ip,
2666 xfs_inode_t *target_dp, 2786 xfs_inode_t *target_dp,
2667 struct xfs_name *target_name, 2787 struct xfs_name *target_name,
2668 xfs_inode_t *target_ip) 2788 xfs_inode_t *target_ip,
2789 unsigned int flags)
2669{ 2790{
2670 xfs_trans_t *tp = NULL; 2791 xfs_trans_t *tp = NULL;
2671 xfs_mount_t *mp = src_dp->i_mount; 2792 xfs_mount_t *mp = src_dp->i_mount;
@@ -2743,6 +2864,18 @@ xfs_rename(
2743 } 2864 }
2744 2865
2745 /* 2866 /*
2867 * Handle RENAME_EXCHANGE flags
2868 */
2869 if (flags & RENAME_EXCHANGE) {
2870 error = xfs_cross_rename(tp, src_dp, src_name, src_ip,
2871 target_dp, target_name, target_ip,
2872 &free_list, &first_block, spaceres);
2873 if (error)
2874 goto abort_return;
2875 goto finish_rename;
2876 }
2877
2878 /*
2746 * Set up the target. 2879 * Set up the target.
2747 */ 2880 */
2748 if (target_ip == NULL) { 2881 if (target_ip == NULL) {
@@ -2881,6 +3014,7 @@ xfs_rename(
2881 if (new_parent) 3014 if (new_parent)
2882 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE); 3015 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
2883 3016
3017finish_rename:
2884 /* 3018 /*
2885 * If this is a synchronous mount, make sure that the 3019 * If this is a synchronous mount, make sure that the
2886 * rename transaction goes to disk before returning to 3020 * rename transaction goes to disk before returning to
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 4ed2ba9342dc..86cd6b39bed7 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -338,7 +338,7 @@ int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
338int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, 338int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
339 struct xfs_inode *src_ip, struct xfs_inode *target_dp, 339 struct xfs_inode *src_ip, struct xfs_inode *target_dp,
340 struct xfs_name *target_name, 340 struct xfs_name *target_name,
341 struct xfs_inode *target_ip); 341 struct xfs_inode *target_ip, unsigned int flags);
342 342
343void xfs_ilock(xfs_inode_t *, uint); 343void xfs_ilock(xfs_inode_t *, uint);
344int xfs_ilock_nowait(xfs_inode_t *, uint); 344int xfs_ilock_nowait(xfs_inode_t *, uint);
@@ -377,6 +377,15 @@ int xfs_droplink(struct xfs_trans *, struct xfs_inode *);
377int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); 377int xfs_bumplink(struct xfs_trans *, struct xfs_inode *);
378 378
379/* from xfs_file.c */ 379/* from xfs_file.c */
380enum xfs_prealloc_flags {
381 XFS_PREALLOC_SET = (1 << 1),
382 XFS_PREALLOC_CLEAR = (1 << 2),
383 XFS_PREALLOC_SYNC = (1 << 3),
384 XFS_PREALLOC_INVISIBLE = (1 << 4),
385};
386
387int xfs_update_prealloc_flags(struct xfs_inode *,
388 enum xfs_prealloc_flags);
380int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); 389int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
381int xfs_iozero(struct xfs_inode *, loff_t, size_t); 390int xfs_iozero(struct xfs_inode *, loff_t, size_t);
382 391
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index a1831980a68e..f7afb86c9148 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -606,11 +606,8 @@ xfs_ioc_space(
606 unsigned int cmd, 606 unsigned int cmd,
607 xfs_flock64_t *bf) 607 xfs_flock64_t *bf)
608{ 608{
609 struct xfs_mount *mp = ip->i_mount;
610 struct xfs_trans *tp;
611 struct iattr iattr; 609 struct iattr iattr;
612 bool setprealloc = false; 610 enum xfs_prealloc_flags flags = 0;
613 bool clrprealloc = false;
614 int error; 611 int error;
615 612
616 /* 613 /*
@@ -630,6 +627,11 @@ xfs_ioc_space(
630 if (!S_ISREG(inode->i_mode)) 627 if (!S_ISREG(inode->i_mode))
631 return -EINVAL; 628 return -EINVAL;
632 629
630 if (filp->f_flags & O_DSYNC)
631 flags |= XFS_PREALLOC_SYNC;
632 if (ioflags & XFS_IO_INVIS)
633 flags |= XFS_PREALLOC_INVISIBLE;
634
633 error = mnt_want_write_file(filp); 635 error = mnt_want_write_file(filp);
634 if (error) 636 if (error)
635 return error; 637 return error;
@@ -673,25 +675,23 @@ xfs_ioc_space(
673 } 675 }
674 676
675 if (bf->l_start < 0 || 677 if (bf->l_start < 0 ||
676 bf->l_start > mp->m_super->s_maxbytes || 678 bf->l_start > inode->i_sb->s_maxbytes ||
677 bf->l_start + bf->l_len < 0 || 679 bf->l_start + bf->l_len < 0 ||
678 bf->l_start + bf->l_len >= mp->m_super->s_maxbytes) { 680 bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) {
679 error = -EINVAL; 681 error = -EINVAL;
680 goto out_unlock; 682 goto out_unlock;
681 } 683 }
682 684
683 switch (cmd) { 685 switch (cmd) {
684 case XFS_IOC_ZERO_RANGE: 686 case XFS_IOC_ZERO_RANGE:
687 flags |= XFS_PREALLOC_SET;
685 error = xfs_zero_file_space(ip, bf->l_start, bf->l_len); 688 error = xfs_zero_file_space(ip, bf->l_start, bf->l_len);
686 if (!error)
687 setprealloc = true;
688 break; 689 break;
689 case XFS_IOC_RESVSP: 690 case XFS_IOC_RESVSP:
690 case XFS_IOC_RESVSP64: 691 case XFS_IOC_RESVSP64:
692 flags |= XFS_PREALLOC_SET;
691 error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len, 693 error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len,
692 XFS_BMAPI_PREALLOC); 694 XFS_BMAPI_PREALLOC);
693 if (!error)
694 setprealloc = true;
695 break; 695 break;
696 case XFS_IOC_UNRESVSP: 696 case XFS_IOC_UNRESVSP:
697 case XFS_IOC_UNRESVSP64: 697 case XFS_IOC_UNRESVSP64:
@@ -701,6 +701,7 @@ xfs_ioc_space(
701 case XFS_IOC_ALLOCSP64: 701 case XFS_IOC_ALLOCSP64:
702 case XFS_IOC_FREESP: 702 case XFS_IOC_FREESP:
703 case XFS_IOC_FREESP64: 703 case XFS_IOC_FREESP64:
704 flags |= XFS_PREALLOC_CLEAR;
704 if (bf->l_start > XFS_ISIZE(ip)) { 705 if (bf->l_start > XFS_ISIZE(ip)) {
705 error = xfs_alloc_file_space(ip, XFS_ISIZE(ip), 706 error = xfs_alloc_file_space(ip, XFS_ISIZE(ip),
706 bf->l_start - XFS_ISIZE(ip), 0); 707 bf->l_start - XFS_ISIZE(ip), 0);
@@ -712,8 +713,6 @@ xfs_ioc_space(
712 iattr.ia_size = bf->l_start; 713 iattr.ia_size = bf->l_start;
713 714
714 error = xfs_setattr_size(ip, &iattr); 715 error = xfs_setattr_size(ip, &iattr);
715 if (!error)
716 clrprealloc = true;
717 break; 716 break;
718 default: 717 default:
719 ASSERT(0); 718 ASSERT(0);
@@ -723,32 +722,7 @@ xfs_ioc_space(
723 if (error) 722 if (error)
724 goto out_unlock; 723 goto out_unlock;
725 724
726 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID); 725 error = xfs_update_prealloc_flags(ip, flags);
727 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_writeid, 0, 0);
728 if (error) {
729 xfs_trans_cancel(tp, 0);
730 goto out_unlock;
731 }
732
733 xfs_ilock(ip, XFS_ILOCK_EXCL);
734 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
735
736 if (!(ioflags & XFS_IO_INVIS)) {
737 ip->i_d.di_mode &= ~S_ISUID;
738 if (ip->i_d.di_mode & S_IXGRP)
739 ip->i_d.di_mode &= ~S_ISGID;
740 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
741 }
742
743 if (setprealloc)
744 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
745 else if (clrprealloc)
746 ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
747
748 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
749 if (filp->f_flags & O_DSYNC)
750 xfs_trans_set_sync(tp);
751 error = xfs_trans_commit(tp, 0);
752 726
753out_unlock: 727out_unlock:
754 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 728 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -1013,20 +987,182 @@ xfs_diflags_to_linux(
1013 inode->i_flags &= ~S_NOATIME; 987 inode->i_flags &= ~S_NOATIME;
1014} 988}
1015 989
1016#define FSX_PROJID 1 990static int
1017#define FSX_EXTSIZE 2 991xfs_ioctl_setattr_xflags(
1018#define FSX_XFLAGS 4 992 struct xfs_trans *tp,
1019#define FSX_NONBLOCK 8 993 struct xfs_inode *ip,
994 struct fsxattr *fa)
995{
996 struct xfs_mount *mp = ip->i_mount;
997
998 /* Can't change realtime flag if any extents are allocated. */
999 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1000 XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & XFS_XFLAG_REALTIME))
1001 return -EINVAL;
1002
1003 /* If realtime flag is set then must have realtime device */
1004 if (fa->fsx_xflags & XFS_XFLAG_REALTIME) {
1005 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
1006 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
1007 return -EINVAL;
1008 }
1009
1010 /*
1011 * Can't modify an immutable/append-only file unless
1012 * we have appropriate permission.
1013 */
1014 if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
1015 (fa->fsx_xflags & (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1016 !capable(CAP_LINUX_IMMUTABLE))
1017 return -EPERM;
1018
1019 xfs_set_diflags(ip, fa->fsx_xflags);
1020 xfs_diflags_to_linux(ip);
1021 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1022 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1023 XFS_STATS_INC(xs_ig_attrchg);
1024 return 0;
1025}
1026
1027/*
1028 * Set up the transaction structure for the setattr operation, checking that we
1029 * have permission to do so. On success, return a clean transaction and the
1030 * inode locked exclusively ready for further operation specific checks. On
1031 * failure, return an error without modifying or locking the inode.
1032 */
1033static struct xfs_trans *
1034xfs_ioctl_setattr_get_trans(
1035 struct xfs_inode *ip)
1036{
1037 struct xfs_mount *mp = ip->i_mount;
1038 struct xfs_trans *tp;
1039 int error;
1040
1041 if (mp->m_flags & XFS_MOUNT_RDONLY)
1042 return ERR_PTR(-EROFS);
1043 if (XFS_FORCED_SHUTDOWN(mp))
1044 return ERR_PTR(-EIO);
1045
1046 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
1047 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
1048 if (error)
1049 goto out_cancel;
1050
1051 xfs_ilock(ip, XFS_ILOCK_EXCL);
1052 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1053
1054 /*
1055 * CAP_FOWNER overrides the following restrictions:
1056 *
1057 * The user ID of the calling process must be equal to the file owner
1058 * ID, except in cases where the CAP_FSETID capability is applicable.
1059 */
1060 if (!inode_owner_or_capable(VFS_I(ip))) {
1061 error = -EPERM;
1062 goto out_cancel;
1063 }
1064
1065 if (mp->m_flags & XFS_MOUNT_WSYNC)
1066 xfs_trans_set_sync(tp);
1067
1068 return tp;
1069
1070out_cancel:
1071 xfs_trans_cancel(tp, 0);
1072 return ERR_PTR(error);
1073}
1074
1075/*
1076 * extent size hint validation is somewhat cumbersome. Rules are:
1077 *
1078 * 1. extent size hint is only valid for directories and regular files
1079 * 2. XFS_XFLAG_EXTSIZE is only valid for regular files
1080 * 3. XFS_XFLAG_EXTSZINHERIT is only valid for directories.
1081 * 4. can only be changed on regular files if no extents are allocated
1082 * 5. can be changed on directories at any time
1083 * 6. extsize hint of 0 turns off hints, clears inode flags.
1084 * 7. Extent size must be a multiple of the appropriate block size.
1085 * 8. for non-realtime files, the extent size hint must be limited
1086 * to half the AG size to avoid alignment extending the extent beyond the
1087 * limits of the AG.
1088 */
1089static int
1090xfs_ioctl_setattr_check_extsize(
1091 struct xfs_inode *ip,
1092 struct fsxattr *fa)
1093{
1094 struct xfs_mount *mp = ip->i_mount;
1095
1096 if ((fa->fsx_xflags & XFS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
1097 return -EINVAL;
1098
1099 if ((fa->fsx_xflags & XFS_XFLAG_EXTSZINHERIT) &&
1100 !S_ISDIR(ip->i_d.di_mode))
1101 return -EINVAL;
1102
1103 if (S_ISREG(ip->i_d.di_mode) && ip->i_d.di_nextents &&
1104 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
1105 return -EINVAL;
1106
1107 if (fa->fsx_extsize != 0) {
1108 xfs_extlen_t size;
1109 xfs_fsblock_t extsize_fsb;
1110
1111 extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1112 if (extsize_fsb > MAXEXTLEN)
1113 return -EINVAL;
1114
1115 if (XFS_IS_REALTIME_INODE(ip) ||
1116 (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1117 size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
1118 } else {
1119 size = mp->m_sb.sb_blocksize;
1120 if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
1121 return -EINVAL;
1122 }
1123
1124 if (fa->fsx_extsize % size)
1125 return -EINVAL;
1126 } else
1127 fa->fsx_xflags &= ~(XFS_XFLAG_EXTSIZE | XFS_XFLAG_EXTSZINHERIT);
1128
1129 return 0;
1130}
1131
1132static int
1133xfs_ioctl_setattr_check_projid(
1134 struct xfs_inode *ip,
1135 struct fsxattr *fa)
1136{
1137 /* Disallow 32bit project ids if projid32bit feature is not enabled. */
1138 if (fa->fsx_projid > (__uint16_t)-1 &&
1139 !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
1140 return -EINVAL;
1141
1142 /*
1143 * Project Quota ID state is only allowed to change from within the init
1144 * namespace. Enforce that restriction only if we are trying to change
1145 * the quota ID state. Everything else is allowed in user namespaces.
1146 */
1147 if (current_user_ns() == &init_user_ns)
1148 return 0;
1149
1150 if (xfs_get_projid(ip) != fa->fsx_projid)
1151 return -EINVAL;
1152 if ((fa->fsx_xflags & XFS_XFLAG_PROJINHERIT) !=
1153 (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
1154 return -EINVAL;
1155
1156 return 0;
1157}
1020 1158
1021STATIC int 1159STATIC int
1022xfs_ioctl_setattr( 1160xfs_ioctl_setattr(
1023 xfs_inode_t *ip, 1161 xfs_inode_t *ip,
1024 struct fsxattr *fa, 1162 struct fsxattr *fa)
1025 int mask)
1026{ 1163{
1027 struct xfs_mount *mp = ip->i_mount; 1164 struct xfs_mount *mp = ip->i_mount;
1028 struct xfs_trans *tp; 1165 struct xfs_trans *tp;
1029 unsigned int lock_flags = 0;
1030 struct xfs_dquot *udqp = NULL; 1166 struct xfs_dquot *udqp = NULL;
1031 struct xfs_dquot *pdqp = NULL; 1167 struct xfs_dquot *pdqp = NULL;
1032 struct xfs_dquot *olddquot = NULL; 1168 struct xfs_dquot *olddquot = NULL;
@@ -1034,17 +1170,9 @@ xfs_ioctl_setattr(
1034 1170
1035 trace_xfs_ioctl_setattr(ip); 1171 trace_xfs_ioctl_setattr(ip);
1036 1172
1037 if (mp->m_flags & XFS_MOUNT_RDONLY) 1173 code = xfs_ioctl_setattr_check_projid(ip, fa);
1038 return -EROFS; 1174 if (code)
1039 if (XFS_FORCED_SHUTDOWN(mp)) 1175 return code;
1040 return -EIO;
1041
1042 /*
1043 * Disallow 32bit project ids when projid32bit feature is not enabled.
1044 */
1045 if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) &&
1046 !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
1047 return -EINVAL;
1048 1176
1049 /* 1177 /*
1050 * If disk quotas is on, we make sure that the dquots do exist on disk, 1178 * If disk quotas is on, we make sure that the dquots do exist on disk,
@@ -1054,7 +1182,7 @@ xfs_ioctl_setattr(
1054 * If the IDs do change before we take the ilock, we're covered 1182 * If the IDs do change before we take the ilock, we're covered
1055 * because the i_*dquot fields will get updated anyway. 1183 * because the i_*dquot fields will get updated anyway.
1056 */ 1184 */
1057 if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) { 1185 if (XFS_IS_QUOTA_ON(mp)) {
1058 code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid, 1186 code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
1059 ip->i_d.di_gid, fa->fsx_projid, 1187 ip->i_d.di_gid, fa->fsx_projid,
1060 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp); 1188 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
@@ -1062,175 +1190,49 @@ xfs_ioctl_setattr(
1062 return code; 1190 return code;
1063 } 1191 }
1064 1192
1065 /* 1193 tp = xfs_ioctl_setattr_get_trans(ip);
1066 * For the other attributes, we acquire the inode lock and 1194 if (IS_ERR(tp)) {
1067 * first do an error checking pass. 1195 code = PTR_ERR(tp);
1068 */ 1196 goto error_free_dquots;
1069 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
1070 code = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
1071 if (code)
1072 goto error_return;
1073
1074 lock_flags = XFS_ILOCK_EXCL;
1075 xfs_ilock(ip, lock_flags);
1076
1077 /*
1078 * CAP_FOWNER overrides the following restrictions:
1079 *
1080 * The user ID of the calling process must be equal
1081 * to the file owner ID, except in cases where the
1082 * CAP_FSETID capability is applicable.
1083 */
1084 if (!inode_owner_or_capable(VFS_I(ip))) {
1085 code = -EPERM;
1086 goto error_return;
1087 }
1088
1089 /*
1090 * Do a quota reservation only if projid is actually going to change.
1091 * Only allow changing of projid from init_user_ns since it is a
1092 * non user namespace aware identifier.
1093 */
1094 if (mask & FSX_PROJID) {
1095 if (current_user_ns() != &init_user_ns) {
1096 code = -EINVAL;
1097 goto error_return;
1098 }
1099
1100 if (XFS_IS_QUOTA_RUNNING(mp) &&
1101 XFS_IS_PQUOTA_ON(mp) &&
1102 xfs_get_projid(ip) != fa->fsx_projid) {
1103 ASSERT(tp);
1104 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL,
1105 pdqp, capable(CAP_FOWNER) ?
1106 XFS_QMOPT_FORCE_RES : 0);
1107 if (code) /* out of quota */
1108 goto error_return;
1109 }
1110 } 1197 }
1111 1198
1112 if (mask & FSX_EXTSIZE) {
1113 /*
1114 * Can't change extent size if any extents are allocated.
1115 */
1116 if (ip->i_d.di_nextents &&
1117 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
1118 fa->fsx_extsize)) {
1119 code = -EINVAL; /* EFBIG? */
1120 goto error_return;
1121 }
1122 1199
1123 /* 1200 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp) &&
1124 * Extent size must be a multiple of the appropriate block 1201 xfs_get_projid(ip) != fa->fsx_projid) {
1125 * size, if set at all. It must also be smaller than the 1202 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL, pdqp,
1126 * maximum extent size supported by the filesystem. 1203 capable(CAP_FOWNER) ? XFS_QMOPT_FORCE_RES : 0);
1127 * 1204 if (code) /* out of quota */
1128 * Also, for non-realtime files, limit the extent size hint to 1205 goto error_trans_cancel;
1129 * half the size of the AGs in the filesystem so alignment
1130 * doesn't result in extents larger than an AG.
1131 */
1132 if (fa->fsx_extsize != 0) {
1133 xfs_extlen_t size;
1134 xfs_fsblock_t extsize_fsb;
1135
1136 extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1137 if (extsize_fsb > MAXEXTLEN) {
1138 code = -EINVAL;
1139 goto error_return;
1140 }
1141
1142 if (XFS_IS_REALTIME_INODE(ip) ||
1143 ((mask & FSX_XFLAGS) &&
1144 (fa->fsx_xflags & XFS_XFLAG_REALTIME))) {
1145 size = mp->m_sb.sb_rextsize <<
1146 mp->m_sb.sb_blocklog;
1147 } else {
1148 size = mp->m_sb.sb_blocksize;
1149 if (extsize_fsb > mp->m_sb.sb_agblocks / 2) {
1150 code = -EINVAL;
1151 goto error_return;
1152 }
1153 }
1154
1155 if (fa->fsx_extsize % size) {
1156 code = -EINVAL;
1157 goto error_return;
1158 }
1159 }
1160 } 1206 }
1161 1207
1208 code = xfs_ioctl_setattr_check_extsize(ip, fa);
1209 if (code)
1210 goto error_trans_cancel;
1162 1211
1163 if (mask & FSX_XFLAGS) { 1212 code = xfs_ioctl_setattr_xflags(tp, ip, fa);
1164 /* 1213 if (code)
1165 * Can't change realtime flag if any extents are allocated. 1214 goto error_trans_cancel;
1166 */
1167 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1168 (XFS_IS_REALTIME_INODE(ip)) !=
1169 (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1170 code = -EINVAL; /* EFBIG? */
1171 goto error_return;
1172 }
1173
1174 /*
1175 * If realtime flag is set then must have realtime data.
1176 */
1177 if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1178 if ((mp->m_sb.sb_rblocks == 0) ||
1179 (mp->m_sb.sb_rextsize == 0) ||
1180 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) {
1181 code = -EINVAL;
1182 goto error_return;
1183 }
1184 }
1185
1186 /*
1187 * Can't modify an immutable/append-only file unless
1188 * we have appropriate permission.
1189 */
1190 if ((ip->i_d.di_flags &
1191 (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
1192 (fa->fsx_xflags &
1193 (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1194 !capable(CAP_LINUX_IMMUTABLE)) {
1195 code = -EPERM;
1196 goto error_return;
1197 }
1198 }
1199
1200 xfs_trans_ijoin(tp, ip, 0);
1201 1215
1202 /* 1216 /*
1203 * Change file ownership. Must be the owner or privileged. 1217 * Change file ownership. Must be the owner or privileged. CAP_FSETID
1218 * overrides the following restrictions:
1219 *
1220 * The set-user-ID and set-group-ID bits of a file will be cleared upon
1221 * successful return from chown()
1204 */ 1222 */
1205 if (mask & FSX_PROJID) {
1206 /*
1207 * CAP_FSETID overrides the following restrictions:
1208 *
1209 * The set-user-ID and set-group-ID bits of a file will be
1210 * cleared upon successful return from chown()
1211 */
1212 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
1213 !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
1214 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
1215
1216 /*
1217 * Change the ownerships and register quota modifications
1218 * in the transaction.
1219 */
1220 if (xfs_get_projid(ip) != fa->fsx_projid) {
1221 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1222 olddquot = xfs_qm_vop_chown(tp, ip,
1223 &ip->i_pdquot, pdqp);
1224 }
1225 ASSERT(ip->i_d.di_version > 1);
1226 xfs_set_projid(ip, fa->fsx_projid);
1227 }
1228 1223
1229 } 1224 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
1225 !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
1226 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
1230 1227
1231 if (mask & FSX_XFLAGS) { 1228 /* Change the ownerships and register project quota modifications */
1232 xfs_set_diflags(ip, fa->fsx_xflags); 1229 if (xfs_get_projid(ip) != fa->fsx_projid) {
1233 xfs_diflags_to_linux(ip); 1230 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1231 olddquot = xfs_qm_vop_chown(tp, ip,
1232 &ip->i_pdquot, pdqp);
1233 }
1234 ASSERT(ip->i_d.di_version > 1);
1235 xfs_set_projid(ip, fa->fsx_projid);
1234 } 1236 }
1235 1237
1236 /* 1238 /*
@@ -1238,34 +1240,12 @@ xfs_ioctl_setattr(
1238 * extent size hint should be set on the inode. If no extent size flags 1240 * extent size hint should be set on the inode. If no extent size flags
1239 * are set on the inode then unconditionally clear the extent size hint. 1241 * are set on the inode then unconditionally clear the extent size hint.
1240 */ 1242 */
1241 if (mask & FSX_EXTSIZE) { 1243 if (ip->i_d.di_flags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
1242 int extsize = 0; 1244 ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1243 1245 else
1244 if (ip->i_d.di_flags & 1246 ip->i_d.di_extsize = 0;
1245 (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
1246 extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1247 ip->i_d.di_extsize = extsize;
1248 }
1249
1250 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1251 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1252
1253 XFS_STATS_INC(xs_ig_attrchg);
1254 1247
1255 /*
1256 * If this is a synchronous mount, make sure that the
1257 * transaction goes to disk before returning to the user.
1258 * This is slightly sub-optimal in that truncates require
1259 * two sync transactions instead of one for wsync filesystems.
1260 * One for the truncate and one for the timestamps since we
1261 * don't want to change the timestamps unless we're sure the
1262 * truncate worked. Truncates are less than 1% of the laddis
1263 * mix so this probably isn't worth the trouble to optimize.
1264 */
1265 if (mp->m_flags & XFS_MOUNT_WSYNC)
1266 xfs_trans_set_sync(tp);
1267 code = xfs_trans_commit(tp, 0); 1248 code = xfs_trans_commit(tp, 0);
1268 xfs_iunlock(ip, lock_flags);
1269 1249
1270 /* 1250 /*
1271 * Release any dquot(s) the inode had kept before chown. 1251 * Release any dquot(s) the inode had kept before chown.
@@ -1276,12 +1256,11 @@ xfs_ioctl_setattr(
1276 1256
1277 return code; 1257 return code;
1278 1258
1279 error_return: 1259error_trans_cancel:
1260 xfs_trans_cancel(tp, 0);
1261error_free_dquots:
1280 xfs_qm_dqrele(udqp); 1262 xfs_qm_dqrele(udqp);
1281 xfs_qm_dqrele(pdqp); 1263 xfs_qm_dqrele(pdqp);
1282 xfs_trans_cancel(tp, 0);
1283 if (lock_flags)
1284 xfs_iunlock(ip, lock_flags);
1285 return code; 1264 return code;
1286} 1265}
1287 1266
@@ -1292,20 +1271,15 @@ xfs_ioc_fssetxattr(
1292 void __user *arg) 1271 void __user *arg)
1293{ 1272{
1294 struct fsxattr fa; 1273 struct fsxattr fa;
1295 unsigned int mask;
1296 int error; 1274 int error;
1297 1275
1298 if (copy_from_user(&fa, arg, sizeof(fa))) 1276 if (copy_from_user(&fa, arg, sizeof(fa)))
1299 return -EFAULT; 1277 return -EFAULT;
1300 1278
1301 mask = FSX_XFLAGS | FSX_EXTSIZE | FSX_PROJID;
1302 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1303 mask |= FSX_NONBLOCK;
1304
1305 error = mnt_want_write_file(filp); 1279 error = mnt_want_write_file(filp);
1306 if (error) 1280 if (error)
1307 return error; 1281 return error;
1308 error = xfs_ioctl_setattr(ip, &fa, mask); 1282 error = xfs_ioctl_setattr(ip, &fa);
1309 mnt_drop_write_file(filp); 1283 mnt_drop_write_file(filp);
1310 return error; 1284 return error;
1311} 1285}
@@ -1325,14 +1299,14 @@ xfs_ioc_getxflags(
1325 1299
1326STATIC int 1300STATIC int
1327xfs_ioc_setxflags( 1301xfs_ioc_setxflags(
1328 xfs_inode_t *ip, 1302 struct xfs_inode *ip,
1329 struct file *filp, 1303 struct file *filp,
1330 void __user *arg) 1304 void __user *arg)
1331{ 1305{
1306 struct xfs_trans *tp;
1332 struct fsxattr fa; 1307 struct fsxattr fa;
1333 unsigned int flags; 1308 unsigned int flags;
1334 unsigned int mask; 1309 int error;
1335 int error;
1336 1310
1337 if (copy_from_user(&flags, arg, sizeof(flags))) 1311 if (copy_from_user(&flags, arg, sizeof(flags)))
1338 return -EFAULT; 1312 return -EFAULT;
@@ -1342,15 +1316,26 @@ xfs_ioc_setxflags(
1342 FS_SYNC_FL)) 1316 FS_SYNC_FL))
1343 return -EOPNOTSUPP; 1317 return -EOPNOTSUPP;
1344 1318
1345 mask = FSX_XFLAGS;
1346 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1347 mask |= FSX_NONBLOCK;
1348 fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); 1319 fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1349 1320
1350 error = mnt_want_write_file(filp); 1321 error = mnt_want_write_file(filp);
1351 if (error) 1322 if (error)
1352 return error; 1323 return error;
1353 error = xfs_ioctl_setattr(ip, &fa, mask); 1324
1325 tp = xfs_ioctl_setattr_get_trans(ip);
1326 if (IS_ERR(tp)) {
1327 error = PTR_ERR(tp);
1328 goto out_drop_write;
1329 }
1330
1331 error = xfs_ioctl_setattr_xflags(tp, ip, &fa);
1332 if (error) {
1333 xfs_trans_cancel(tp, 0);
1334 goto out_drop_write;
1335 }
1336
1337 error = xfs_trans_commit(tp, 0);
1338out_drop_write:
1354 mnt_drop_write_file(filp); 1339 mnt_drop_write_file(filp);
1355 return error; 1340 return error;
1356} 1341}
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index ec6772866f3d..bfc7c7c8a0c8 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -423,7 +423,7 @@ xfs_compat_attrmulti_by_handle(
423 423
424 ops = memdup_user(compat_ptr(am_hreq.ops), size); 424 ops = memdup_user(compat_ptr(am_hreq.ops), size);
425 if (IS_ERR(ops)) { 425 if (IS_ERR(ops)) {
426 error = -PTR_ERR(ops); 426 error = PTR_ERR(ops);
427 goto out_dput; 427 goto out_dput;
428 } 428 }
429 429
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index c980e2a5086b..ccb1dd0d509e 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -802,7 +802,7 @@ int
802xfs_iomap_write_unwritten( 802xfs_iomap_write_unwritten(
803 xfs_inode_t *ip, 803 xfs_inode_t *ip,
804 xfs_off_t offset, 804 xfs_off_t offset,
805 size_t count) 805 xfs_off_t count)
806{ 806{
807 xfs_mount_t *mp = ip->i_mount; 807 xfs_mount_t *mp = ip->i_mount;
808 xfs_fileoff_t offset_fsb; 808 xfs_fileoff_t offset_fsb;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 411fbb8919ef..8688e663d744 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -27,6 +27,6 @@ int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t,
27 struct xfs_bmbt_irec *); 27 struct xfs_bmbt_irec *);
28int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, 28int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t,
29 struct xfs_bmbt_irec *); 29 struct xfs_bmbt_irec *);
30int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t); 30int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t);
31 31
32#endif /* __XFS_IOMAP_H__*/ 32#endif /* __XFS_IOMAP_H__*/
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index c50311cae1b1..ce80eeb8faa4 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -380,18 +380,27 @@ xfs_vn_rename(
380 struct inode *odir, 380 struct inode *odir,
381 struct dentry *odentry, 381 struct dentry *odentry,
382 struct inode *ndir, 382 struct inode *ndir,
383 struct dentry *ndentry) 383 struct dentry *ndentry,
384 unsigned int flags)
384{ 385{
385 struct inode *new_inode = ndentry->d_inode; 386 struct inode *new_inode = ndentry->d_inode;
387 int omode = 0;
386 struct xfs_name oname; 388 struct xfs_name oname;
387 struct xfs_name nname; 389 struct xfs_name nname;
388 390
389 xfs_dentry_to_name(&oname, odentry, 0); 391 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
392 return -EINVAL;
393
394 /* if we are exchanging files, we need to set i_mode of both files */
395 if (flags & RENAME_EXCHANGE)
396 omode = ndentry->d_inode->i_mode;
397
398 xfs_dentry_to_name(&oname, odentry, omode);
390 xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode); 399 xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode);
391 400
392 return xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), 401 return xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
393 XFS_I(ndir), &nname, new_inode ? 402 XFS_I(ndir), &nname,
394 XFS_I(new_inode) : NULL); 403 new_inode ? XFS_I(new_inode) : NULL, flags);
395} 404}
396 405
397/* 406/*
@@ -1144,7 +1153,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
1144 */ 1153 */
1145 .rmdir = xfs_vn_unlink, 1154 .rmdir = xfs_vn_unlink,
1146 .mknod = xfs_vn_mknod, 1155 .mknod = xfs_vn_mknod,
1147 .rename = xfs_vn_rename, 1156 .rename2 = xfs_vn_rename,
1148 .get_acl = xfs_get_acl, 1157 .get_acl = xfs_get_acl,
1149 .set_acl = xfs_set_acl, 1158 .set_acl = xfs_set_acl,
1150 .getattr = xfs_vn_getattr, 1159 .getattr = xfs_vn_getattr,
@@ -1172,7 +1181,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1172 */ 1181 */
1173 .rmdir = xfs_vn_unlink, 1182 .rmdir = xfs_vn_unlink,
1174 .mknod = xfs_vn_mknod, 1183 .mknod = xfs_vn_mknod,
1175 .rename = xfs_vn_rename, 1184 .rename2 = xfs_vn_rename,
1176 .get_acl = xfs_get_acl, 1185 .get_acl = xfs_get_acl,
1177 .set_acl = xfs_set_acl, 1186 .set_acl = xfs_set_acl,
1178 .getattr = xfs_vn_getattr, 1187 .getattr = xfs_vn_getattr,
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index e408bf5a3ff7..bcc7cfabb787 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -33,6 +33,7 @@
33#include "xfs_fsops.h" 33#include "xfs_fsops.h"
34#include "xfs_cksum.h" 34#include "xfs_cksum.h"
35#include "xfs_sysfs.h" 35#include "xfs_sysfs.h"
36#include "xfs_sb.h"
36 37
37kmem_zone_t *xfs_log_ticket_zone; 38kmem_zone_t *xfs_log_ticket_zone;
38 39
@@ -1290,9 +1291,20 @@ xfs_log_worker(
1290 struct xfs_mount *mp = log->l_mp; 1291 struct xfs_mount *mp = log->l_mp;
1291 1292
1292 /* dgc: errors ignored - not fatal and nowhere to report them */ 1293 /* dgc: errors ignored - not fatal and nowhere to report them */
1293 if (xfs_log_need_covered(mp)) 1294 if (xfs_log_need_covered(mp)) {
1294 xfs_fs_log_dummy(mp); 1295 /*
1295 else 1296 * Dump a transaction into the log that contains no real change.
1297 * This is needed to stamp the current tail LSN into the log
1298 * during the covering operation.
1299 *
1300 * We cannot use an inode here for this - that will push dirty
1301 * state back up into the VFS and then periodic inode flushing
1302 * will prevent log covering from making progress. Hence we
1303 * synchronously log the superblock instead to ensure the
1304 * superblock is immediately unpinned and can be written back.
1305 */
1306 xfs_sync_sb(mp, true);
1307 } else
1296 xfs_log_force(mp, 0); 1308 xfs_log_force(mp, 0);
1297 1309
1298 /* start pushing all the metadata that is currently dirty */ 1310 /* start pushing all the metadata that is currently dirty */
@@ -1395,6 +1407,8 @@ xlog_alloc_log(
1395 ASSERT(xfs_buf_islocked(bp)); 1407 ASSERT(xfs_buf_islocked(bp));
1396 xfs_buf_unlock(bp); 1408 xfs_buf_unlock(bp);
1397 1409
1410 /* use high priority wq for log I/O completion */
1411 bp->b_ioend_wq = mp->m_log_workqueue;
1398 bp->b_iodone = xlog_iodone; 1412 bp->b_iodone = xlog_iodone;
1399 log->l_xbuf = bp; 1413 log->l_xbuf = bp;
1400 1414
@@ -1427,6 +1441,8 @@ xlog_alloc_log(
1427 ASSERT(xfs_buf_islocked(bp)); 1441 ASSERT(xfs_buf_islocked(bp));
1428 xfs_buf_unlock(bp); 1442 xfs_buf_unlock(bp);
1429 1443
1444 /* use high priority wq for log I/O completion */
1445 bp->b_ioend_wq = mp->m_log_workqueue;
1430 bp->b_iodone = xlog_iodone; 1446 bp->b_iodone = xlog_iodone;
1431 iclog->ic_bp = bp; 1447 iclog->ic_bp = bp;
1432 iclog->ic_data = bp->b_addr; 1448 iclog->ic_data = bp->b_addr;
@@ -1806,8 +1822,6 @@ xlog_sync(
1806 XFS_BUF_ZEROFLAGS(bp); 1822 XFS_BUF_ZEROFLAGS(bp);
1807 XFS_BUF_ASYNC(bp); 1823 XFS_BUF_ASYNC(bp);
1808 bp->b_flags |= XBF_SYNCIO; 1824 bp->b_flags |= XBF_SYNCIO;
1809 /* use high priority completion wq */
1810 bp->b_ioend_wq = log->l_mp->m_log_workqueue;
1811 1825
1812 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { 1826 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
1813 bp->b_flags |= XBF_FUA; 1827 bp->b_flags |= XBF_FUA;
@@ -1856,8 +1870,6 @@ xlog_sync(
1856 bp->b_flags |= XBF_SYNCIO; 1870 bp->b_flags |= XBF_SYNCIO;
1857 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) 1871 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1858 bp->b_flags |= XBF_FUA; 1872 bp->b_flags |= XBF_FUA;
1859 /* use high priority completion wq */
1860 bp->b_ioend_wq = log->l_mp->m_log_workqueue;
1861 1873
1862 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); 1874 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1863 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); 1875 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
@@ -2027,7 +2039,7 @@ xlog_print_tic_res(
2027 " total reg = %u bytes (o/flow = %u bytes)\n" 2039 " total reg = %u bytes (o/flow = %u bytes)\n"
2028 " ophdrs = %u (ophdr space = %u bytes)\n" 2040 " ophdrs = %u (ophdr space = %u bytes)\n"
2029 " ophdr + reg = %u bytes\n" 2041 " ophdr + reg = %u bytes\n"
2030 " num regions = %u\n", 2042 " num regions = %u",
2031 ((ticket->t_trans_type <= 0 || 2043 ((ticket->t_trans_type <= 0 ||
2032 ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ? 2044 ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
2033 "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]), 2045 "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]),
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d3d38836f87f..4fa80e63eea2 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -408,11 +408,11 @@ xfs_update_alignment(xfs_mount_t *mp)
408 if (xfs_sb_version_hasdalign(sbp)) { 408 if (xfs_sb_version_hasdalign(sbp)) {
409 if (sbp->sb_unit != mp->m_dalign) { 409 if (sbp->sb_unit != mp->m_dalign) {
410 sbp->sb_unit = mp->m_dalign; 410 sbp->sb_unit = mp->m_dalign;
411 mp->m_update_flags |= XFS_SB_UNIT; 411 mp->m_update_sb = true;
412 } 412 }
413 if (sbp->sb_width != mp->m_swidth) { 413 if (sbp->sb_width != mp->m_swidth) {
414 sbp->sb_width = mp->m_swidth; 414 sbp->sb_width = mp->m_swidth;
415 mp->m_update_flags |= XFS_SB_WIDTH; 415 mp->m_update_sb = true;
416 } 416 }
417 } else { 417 } else {
418 xfs_warn(mp, 418 xfs_warn(mp,
@@ -583,38 +583,19 @@ int
583xfs_mount_reset_sbqflags( 583xfs_mount_reset_sbqflags(
584 struct xfs_mount *mp) 584 struct xfs_mount *mp)
585{ 585{
586 int error;
587 struct xfs_trans *tp;
588
589 mp->m_qflags = 0; 586 mp->m_qflags = 0;
590 587
591 /* 588 /* It is OK to look at sb_qflags in the mount path without m_sb_lock. */
592 * It is OK to look at sb_qflags here in mount path,
593 * without m_sb_lock.
594 */
595 if (mp->m_sb.sb_qflags == 0) 589 if (mp->m_sb.sb_qflags == 0)
596 return 0; 590 return 0;
597 spin_lock(&mp->m_sb_lock); 591 spin_lock(&mp->m_sb_lock);
598 mp->m_sb.sb_qflags = 0; 592 mp->m_sb.sb_qflags = 0;
599 spin_unlock(&mp->m_sb_lock); 593 spin_unlock(&mp->m_sb_lock);
600 594
601 /* 595 if (!xfs_fs_writable(mp, SB_FREEZE_WRITE))
602 * If the fs is readonly, let the incore superblock run
603 * with quotas off but don't flush the update out to disk
604 */
605 if (mp->m_flags & XFS_MOUNT_RDONLY)
606 return 0; 596 return 0;
607 597
608 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); 598 return xfs_sync_sb(mp, false);
609 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0);
610 if (error) {
611 xfs_trans_cancel(tp, 0);
612 xfs_alert(mp, "%s: Superblock update failed!", __func__);
613 return error;
614 }
615
616 xfs_mod_sb(tp, XFS_SB_QFLAGS);
617 return xfs_trans_commit(tp, 0);
618} 599}
619 600
620__uint64_t 601__uint64_t
@@ -659,26 +640,25 @@ xfs_mountfs(
659 xfs_sb_mount_common(mp, sbp); 640 xfs_sb_mount_common(mp, sbp);
660 641
661 /* 642 /*
662 * Check for a mismatched features2 values. Older kernels 643 * Check for a mismatched features2 values. Older kernels read & wrote
663 * read & wrote into the wrong sb offset for sb_features2 644 * into the wrong sb offset for sb_features2 on some platforms due to
664 * on some platforms due to xfs_sb_t not being 64bit size aligned 645 * xfs_sb_t not being 64bit size aligned when sb_features2 was added,
665 * when sb_features2 was added, which made older superblock 646 * which made older superblock reading/writing routines swap it as a
666 * reading/writing routines swap it as a 64-bit value. 647 * 64-bit value.
667 * 648 *
668 * For backwards compatibility, we make both slots equal. 649 * For backwards compatibility, we make both slots equal.
669 * 650 *
670 * If we detect a mismatched field, we OR the set bits into the 651 * If we detect a mismatched field, we OR the set bits into the existing
671 * existing features2 field in case it has already been modified; we 652 * features2 field in case it has already been modified; we don't want
672 * don't want to lose any features. We then update the bad location 653 * to lose any features. We then update the bad location with the ORed
673 * with the ORed value so that older kernels will see any features2 654 * value so that older kernels will see any features2 flags. The
674 * flags, and mark the two fields as needing updates once the 655 * superblock writeback code ensures the new sb_features2 is copied to
675 * transaction subsystem is online. 656 * sb_bad_features2 before it is logged or written to disk.
676 */ 657 */
677 if (xfs_sb_has_mismatched_features2(sbp)) { 658 if (xfs_sb_has_mismatched_features2(sbp)) {
678 xfs_warn(mp, "correcting sb_features alignment problem"); 659 xfs_warn(mp, "correcting sb_features alignment problem");
679 sbp->sb_features2 |= sbp->sb_bad_features2; 660 sbp->sb_features2 |= sbp->sb_bad_features2;
680 sbp->sb_bad_features2 = sbp->sb_features2; 661 mp->m_update_sb = true;
681 mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
682 662
683 /* 663 /*
684 * Re-check for ATTR2 in case it was found in bad_features2 664 * Re-check for ATTR2 in case it was found in bad_features2
@@ -692,17 +672,17 @@ xfs_mountfs(
692 if (xfs_sb_version_hasattr2(&mp->m_sb) && 672 if (xfs_sb_version_hasattr2(&mp->m_sb) &&
693 (mp->m_flags & XFS_MOUNT_NOATTR2)) { 673 (mp->m_flags & XFS_MOUNT_NOATTR2)) {
694 xfs_sb_version_removeattr2(&mp->m_sb); 674 xfs_sb_version_removeattr2(&mp->m_sb);
695 mp->m_update_flags |= XFS_SB_FEATURES2; 675 mp->m_update_sb = true;
696 676
697 /* update sb_versionnum for the clearing of the morebits */ 677 /* update sb_versionnum for the clearing of the morebits */
698 if (!sbp->sb_features2) 678 if (!sbp->sb_features2)
699 mp->m_update_flags |= XFS_SB_VERSIONNUM; 679 mp->m_update_sb = true;
700 } 680 }
701 681
702 /* always use v2 inodes by default now */ 682 /* always use v2 inodes by default now */
703 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { 683 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
704 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; 684 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
705 mp->m_update_flags |= XFS_SB_VERSIONNUM; 685 mp->m_update_sb = true;
706 } 686 }
707 687
708 /* 688 /*
@@ -895,8 +875,8 @@ xfs_mountfs(
895 * the next remount into writeable mode. Otherwise we would never 875 * the next remount into writeable mode. Otherwise we would never
896 * perform the update e.g. for the root filesystem. 876 * perform the update e.g. for the root filesystem.
897 */ 877 */
898 if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { 878 if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
899 error = xfs_mount_log_sb(mp, mp->m_update_flags); 879 error = xfs_sync_sb(mp, false);
900 if (error) { 880 if (error) {
901 xfs_warn(mp, "failed to write sb changes"); 881 xfs_warn(mp, "failed to write sb changes");
902 goto out_rtunmount; 882 goto out_rtunmount;
@@ -1103,9 +1083,6 @@ xfs_fs_writable(
1103int 1083int
1104xfs_log_sbcount(xfs_mount_t *mp) 1084xfs_log_sbcount(xfs_mount_t *mp)
1105{ 1085{
1106 xfs_trans_t *tp;
1107 int error;
1108
1109 /* allow this to proceed during the freeze sequence... */ 1086 /* allow this to proceed during the freeze sequence... */
1110 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE)) 1087 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
1111 return 0; 1088 return 0;
@@ -1119,17 +1096,7 @@ xfs_log_sbcount(xfs_mount_t *mp)
1119 if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) 1096 if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
1120 return 0; 1097 return 0;
1121 1098
1122 tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); 1099 return xfs_sync_sb(mp, true);
1123 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
1124 if (error) {
1125 xfs_trans_cancel(tp, 0);
1126 return error;
1127 }
1128
1129 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
1130 xfs_trans_set_sync(tp);
1131 error = xfs_trans_commit(tp, 0);
1132 return error;
1133} 1100}
1134 1101
1135/* 1102/*
@@ -1423,34 +1390,6 @@ xfs_freesb(
1423} 1390}
1424 1391
1425/* 1392/*
1426 * Used to log changes to the superblock unit and width fields which could
1427 * be altered by the mount options, as well as any potential sb_features2
1428 * fixup. Only the first superblock is updated.
1429 */
1430int
1431xfs_mount_log_sb(
1432 xfs_mount_t *mp,
1433 __int64_t fields)
1434{
1435 xfs_trans_t *tp;
1436 int error;
1437
1438 ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
1439 XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2 |
1440 XFS_SB_VERSIONNUM));
1441
1442 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
1443 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
1444 if (error) {
1445 xfs_trans_cancel(tp, 0);
1446 return error;
1447 }
1448 xfs_mod_sb(tp, fields);
1449 error = xfs_trans_commit(tp, 0);
1450 return error;
1451}
1452
1453/*
1454 * If the underlying (data/log/rt) device is readonly, there are some 1393 * If the underlying (data/log/rt) device is readonly, there are some
1455 * operations that cannot proceed. 1394 * operations that cannot proceed.
1456 */ 1395 */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 22ccf69d4d3c..a5b2ff822653 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -162,8 +162,7 @@ typedef struct xfs_mount {
162 struct delayed_work m_reclaim_work; /* background inode reclaim */ 162 struct delayed_work m_reclaim_work; /* background inode reclaim */
163 struct delayed_work m_eofblocks_work; /* background eof blocks 163 struct delayed_work m_eofblocks_work; /* background eof blocks
164 trimming */ 164 trimming */
165 __int64_t m_update_flags; /* sb flags we need to update 165 bool m_update_sb; /* sb needs update in mount */
166 on the next remount,rw */
167 int64_t m_low_space[XFS_LOWSP_MAX]; 166 int64_t m_low_space[XFS_LOWSP_MAX];
168 /* low free space thresholds */ 167 /* low free space thresholds */
169 struct xfs_kobj m_kobj; 168 struct xfs_kobj m_kobj;
@@ -378,7 +377,7 @@ extern void xfs_unmountfs(xfs_mount_t *);
378extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); 377extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
379extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, 378extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
380 uint, int); 379 uint, int);
381extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); 380extern int xfs_mount_log_sb(xfs_mount_t *);
382extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 381extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
383extern int xfs_readsb(xfs_mount_t *, int); 382extern int xfs_readsb(xfs_mount_t *, int);
384extern void xfs_freesb(xfs_mount_t *); 383extern void xfs_freesb(xfs_mount_t *);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 79fb19dd9c83..3e8186279541 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -714,7 +714,6 @@ STATIC int
714xfs_qm_qino_alloc( 714xfs_qm_qino_alloc(
715 xfs_mount_t *mp, 715 xfs_mount_t *mp,
716 xfs_inode_t **ip, 716 xfs_inode_t **ip,
717 __int64_t sbfields,
718 uint flags) 717 uint flags)
719{ 718{
720 xfs_trans_t *tp; 719 xfs_trans_t *tp;
@@ -777,11 +776,6 @@ xfs_qm_qino_alloc(
777 spin_lock(&mp->m_sb_lock); 776 spin_lock(&mp->m_sb_lock);
778 if (flags & XFS_QMOPT_SBVERSION) { 777 if (flags & XFS_QMOPT_SBVERSION) {
779 ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); 778 ASSERT(!xfs_sb_version_hasquota(&mp->m_sb));
780 ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
781 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | XFS_SB_QFLAGS)) ==
782 (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
783 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
784 XFS_SB_QFLAGS));
785 779
786 xfs_sb_version_addquota(&mp->m_sb); 780 xfs_sb_version_addquota(&mp->m_sb);
787 mp->m_sb.sb_uquotino = NULLFSINO; 781 mp->m_sb.sb_uquotino = NULLFSINO;
@@ -798,7 +792,7 @@ xfs_qm_qino_alloc(
798 else 792 else
799 mp->m_sb.sb_pquotino = (*ip)->i_ino; 793 mp->m_sb.sb_pquotino = (*ip)->i_ino;
800 spin_unlock(&mp->m_sb_lock); 794 spin_unlock(&mp->m_sb_lock);
801 xfs_mod_sb(tp, sbfields); 795 xfs_log_sb(tp);
802 796
803 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { 797 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
804 xfs_alert(mp, "%s failed (error %d)!", __func__, error); 798 xfs_alert(mp, "%s failed (error %d)!", __func__, error);
@@ -1451,7 +1445,7 @@ xfs_qm_mount_quotas(
1451 spin_unlock(&mp->m_sb_lock); 1445 spin_unlock(&mp->m_sb_lock);
1452 1446
1453 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { 1447 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) {
1454 if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { 1448 if (xfs_sync_sb(mp, false)) {
1455 /* 1449 /*
1456 * We could only have been turning quotas off. 1450 * We could only have been turning quotas off.
1457 * We aren't in very good shape actually because 1451 * We aren't in very good shape actually because
@@ -1482,7 +1476,6 @@ xfs_qm_init_quotainos(
1482 struct xfs_inode *gip = NULL; 1476 struct xfs_inode *gip = NULL;
1483 struct xfs_inode *pip = NULL; 1477 struct xfs_inode *pip = NULL;
1484 int error; 1478 int error;
1485 __int64_t sbflags = 0;
1486 uint flags = 0; 1479 uint flags = 0;
1487 1480
1488 ASSERT(mp->m_quotainfo); 1481 ASSERT(mp->m_quotainfo);
@@ -1517,9 +1510,6 @@ xfs_qm_init_quotainos(
1517 } 1510 }
1518 } else { 1511 } else {
1519 flags |= XFS_QMOPT_SBVERSION; 1512 flags |= XFS_QMOPT_SBVERSION;
1520 sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
1521 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
1522 XFS_SB_QFLAGS);
1523 } 1513 }
1524 1514
1525 /* 1515 /*
@@ -1530,7 +1520,6 @@ xfs_qm_init_quotainos(
1530 */ 1520 */
1531 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { 1521 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
1532 error = xfs_qm_qino_alloc(mp, &uip, 1522 error = xfs_qm_qino_alloc(mp, &uip,
1533 sbflags | XFS_SB_UQUOTINO,
1534 flags | XFS_QMOPT_UQUOTA); 1523 flags | XFS_QMOPT_UQUOTA);
1535 if (error) 1524 if (error)
1536 goto error_rele; 1525 goto error_rele;
@@ -1539,7 +1528,6 @@ xfs_qm_init_quotainos(
1539 } 1528 }
1540 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { 1529 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
1541 error = xfs_qm_qino_alloc(mp, &gip, 1530 error = xfs_qm_qino_alloc(mp, &gip,
1542 sbflags | XFS_SB_GQUOTINO,
1543 flags | XFS_QMOPT_GQUOTA); 1531 flags | XFS_QMOPT_GQUOTA);
1544 if (error) 1532 if (error)
1545 goto error_rele; 1533 goto error_rele;
@@ -1548,7 +1536,6 @@ xfs_qm_init_quotainos(
1548 } 1536 }
1549 if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) { 1537 if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) {
1550 error = xfs_qm_qino_alloc(mp, &pip, 1538 error = xfs_qm_qino_alloc(mp, &pip,
1551 sbflags | XFS_SB_PQUOTINO,
1552 flags | XFS_QMOPT_PQUOTA); 1539 flags | XFS_QMOPT_PQUOTA);
1553 if (error) 1540 if (error)
1554 goto error_rele; 1541 goto error_rele;
@@ -1587,32 +1574,6 @@ xfs_qm_dqfree_one(
1587 xfs_qm_dqdestroy(dqp); 1574 xfs_qm_dqdestroy(dqp);
1588} 1575}
1589 1576
1590/*
1591 * Start a transaction and write the incore superblock changes to
1592 * disk. flags parameter indicates which fields have changed.
1593 */
1594int
1595xfs_qm_write_sb_changes(
1596 xfs_mount_t *mp,
1597 __int64_t flags)
1598{
1599 xfs_trans_t *tp;
1600 int error;
1601
1602 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
1603 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0);
1604 if (error) {
1605 xfs_trans_cancel(tp, 0);
1606 return error;
1607 }
1608
1609 xfs_mod_sb(tp, flags);
1610 error = xfs_trans_commit(tp, 0);
1611
1612 return error;
1613}
1614
1615
1616/* --------------- utility functions for vnodeops ---------------- */ 1577/* --------------- utility functions for vnodeops ---------------- */
1617 1578
1618 1579
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 41f6c0b9d51c..0d4d3590cf85 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -157,7 +157,6 @@ struct xfs_dquot_acct {
157#define XFS_QM_RTBWARNLIMIT 5 157#define XFS_QM_RTBWARNLIMIT 5
158 158
159extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); 159extern void xfs_qm_destroy_quotainfo(struct xfs_mount *);
160extern int xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t);
161 160
162/* dquot stuff */ 161/* dquot stuff */
163extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); 162extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index d56a4f5155d5..9b965db45800 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -91,8 +91,7 @@ xfs_qm_scall_quotaoff(
91 mutex_unlock(&q->qi_quotaofflock); 91 mutex_unlock(&q->qi_quotaofflock);
92 92
93 /* XXX what to do if error ? Revert back to old vals incore ? */ 93 /* XXX what to do if error ? Revert back to old vals incore ? */
94 error = xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS); 94 return xfs_sync_sb(mp, false);
95 return error;
96 } 95 }
97 96
98 dqtype = 0; 97 dqtype = 0;
@@ -313,7 +312,6 @@ xfs_qm_scall_quotaon(
313{ 312{
314 int error; 313 int error;
315 uint qf; 314 uint qf;
316 __int64_t sbflags;
317 315
318 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); 316 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
319 /* 317 /*
@@ -321,8 +319,6 @@ xfs_qm_scall_quotaon(
321 */ 319 */
322 flags &= ~(XFS_ALL_QUOTA_ACCT); 320 flags &= ~(XFS_ALL_QUOTA_ACCT);
323 321
324 sbflags = 0;
325
326 if (flags == 0) { 322 if (flags == 0) {
327 xfs_debug(mp, "%s: zero flags, m_qflags=%x", 323 xfs_debug(mp, "%s: zero flags, m_qflags=%x",
328 __func__, mp->m_qflags); 324 __func__, mp->m_qflags);
@@ -363,11 +359,11 @@ xfs_qm_scall_quotaon(
363 /* 359 /*
364 * There's nothing to change if it's the same. 360 * There's nothing to change if it's the same.
365 */ 361 */
366 if ((qf & flags) == flags && sbflags == 0) 362 if ((qf & flags) == flags)
367 return -EEXIST; 363 return -EEXIST;
368 sbflags |= XFS_SB_QFLAGS;
369 364
370 if ((error = xfs_qm_write_sb_changes(mp, sbflags))) 365 error = xfs_sync_sb(mp, false);
366 if (error)
371 return error; 367 return error;
372 /* 368 /*
373 * If we aren't trying to switch on quota enforcement, we are done. 369 * If we aren't trying to switch on quota enforcement, we are done.
@@ -774,7 +770,7 @@ xfs_qm_log_quotaoff(
774 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 770 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
775 spin_unlock(&mp->m_sb_lock); 771 spin_unlock(&mp->m_sb_lock);
776 772
777 xfs_mod_sb(tp, XFS_SB_QFLAGS); 773 xfs_log_sb(tp);
778 774
779 /* 775 /*
780 * We have to make sure that the transaction is secure on disk before we 776 * We have to make sure that the transaction is secure on disk before we
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 19cbda196369..f2449fd86926 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -685,7 +685,7 @@ xfs_blkdev_get(
685 mp); 685 mp);
686 if (IS_ERR(*bdevp)) { 686 if (IS_ERR(*bdevp)) {
687 error = PTR_ERR(*bdevp); 687 error = PTR_ERR(*bdevp);
688 xfs_warn(mp, "Invalid device [%s], error=%d\n", name, error); 688 xfs_warn(mp, "Invalid device [%s], error=%d", name, error);
689 } 689 }
690 690
691 return error; 691 return error;
@@ -1111,6 +1111,11 @@ xfs_fs_statfs(
1111 statp->f_files, 1111 statp->f_files,
1112 mp->m_maxicount); 1112 mp->m_maxicount);
1113 1113
1114 /* If sb_icount overshot maxicount, report actual allocation */
1115 statp->f_files = max_t(typeof(statp->f_files),
1116 statp->f_files,
1117 sbp->sb_icount);
1118
1114 /* make sure statp->f_ffree does not underflow */ 1119 /* make sure statp->f_ffree does not underflow */
1115 ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); 1120 ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
1116 statp->f_ffree = max_t(__int64_t, ffree, 0); 1121 statp->f_ffree = max_t(__int64_t, ffree, 0);
@@ -1257,13 +1262,13 @@ xfs_fs_remount(
1257 * If this is the first remount to writeable state we 1262 * If this is the first remount to writeable state we
1258 * might have some superblock changes to update. 1263 * might have some superblock changes to update.
1259 */ 1264 */
1260 if (mp->m_update_flags) { 1265 if (mp->m_update_sb) {
1261 error = xfs_mount_log_sb(mp, mp->m_update_flags); 1266 error = xfs_sync_sb(mp, false);
1262 if (error) { 1267 if (error) {
1263 xfs_warn(mp, "failed to write sb changes"); 1268 xfs_warn(mp, "failed to write sb changes");
1264 return error; 1269 return error;
1265 } 1270 }
1266 mp->m_update_flags = 0; 1271 mp->m_update_sb = false;
1267 } 1272 }
1268 1273
1269 /* 1274 /*
@@ -1293,8 +1298,9 @@ xfs_fs_remount(
1293 1298
1294/* 1299/*
1295 * Second stage of a freeze. The data is already frozen so we only 1300 * Second stage of a freeze. The data is already frozen so we only
1296 * need to take care of the metadata. Once that's done write a dummy 1301 * need to take care of the metadata. Once that's done sync the superblock
1297 * record to dirty the log in case of a crash while frozen. 1302 * to the log to dirty it in case of a crash while frozen. This ensures that we
1303 * will recover the unlinked inode lists on the next mount.
1298 */ 1304 */
1299STATIC int 1305STATIC int
1300xfs_fs_freeze( 1306xfs_fs_freeze(
@@ -1304,7 +1310,7 @@ xfs_fs_freeze(
1304 1310
1305 xfs_save_resvblks(mp); 1311 xfs_save_resvblks(mp);
1306 xfs_quiesce_attr(mp); 1312 xfs_quiesce_attr(mp);
1307 return xfs_fs_log_dummy(mp); 1313 return xfs_sync_sb(mp, true);
1308} 1314}
1309 1315
1310STATIC int 1316STATIC int
diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c
index 1743b9f8e23d..a0c8067cea6f 100644
--- a/fs/xfs/xfs_sysctl.c
+++ b/fs/xfs/xfs_sysctl.c
@@ -149,24 +149,6 @@ static struct ctl_table xfs_table[] = {
149 .extra2 = &xfs_params.inherit_noatim.max 149 .extra2 = &xfs_params.inherit_noatim.max
150 }, 150 },
151 { 151 {
152 .procname = "xfsbufd_centisecs",
153 .data = &xfs_params.xfs_buf_timer.val,
154 .maxlen = sizeof(int),
155 .mode = 0644,
156 .proc_handler = proc_dointvec_minmax,
157 .extra1 = &xfs_params.xfs_buf_timer.min,
158 .extra2 = &xfs_params.xfs_buf_timer.max
159 },
160 {
161 .procname = "age_buffer_centisecs",
162 .data = &xfs_params.xfs_buf_age.val,
163 .maxlen = sizeof(int),
164 .mode = 0644,
165 .proc_handler = proc_dointvec_minmax,
166 .extra1 = &xfs_params.xfs_buf_age.min,
167 .extra2 = &xfs_params.xfs_buf_age.max
168 },
169 {
170 .procname = "inherit_nosymlinks", 152 .procname = "inherit_nosymlinks",
171 .data = &xfs_params.inherit_nosym.val, 153 .data = &xfs_params.inherit_nosym.val,
172 .maxlen = sizeof(int), 154 .maxlen = sizeof(int),
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index fa3135b9bf04..eb90cd59a0ec 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -472,6 +472,7 @@ xfs_trans_apply_sb_deltas(
472 whole = 1; 472 whole = 1;
473 } 473 }
474 474
475 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
475 if (whole) 476 if (whole)
476 /* 477 /*
477 * Log the whole thing, the fields are noncontiguous. 478 * Log the whole thing, the fields are noncontiguous.
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 0a4d4ab6d9a9..75798412859a 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -327,9 +327,10 @@ xfs_trans_read_buf_map(
327 return -EIO; 327 return -EIO;
328 } 328 }
329 329
330 if (tp) 330 if (tp) {
331 _xfs_trans_bjoin(tp, bp, 1); 331 _xfs_trans_bjoin(tp, bp, 1);
332 trace_xfs_trans_read_buf(bp->b_fspriv); 332 trace_xfs_trans_read_buf(bp->b_fspriv);
333 }
333 *bpp = bp; 334 *bpp = bp;
334 return 0; 335 return 0;
335 336