diff options
40 files changed, 733 insertions, 441 deletions
diff --git a/Documentation/ABI/testing/sysfs-fs-xfs b/Documentation/ABI/testing/sysfs-fs-xfs new file mode 100644 index 000000000000..ea0cc8c42093 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-fs-xfs | |||
@@ -0,0 +1,39 @@ | |||
1 | What: /sys/fs/xfs/<disk>/log/log_head_lsn | ||
2 | Date: July 2014 | ||
3 | KernelVersion: 3.17 | ||
4 | Contact: xfs@oss.sgi.com | ||
5 | Description: | ||
6 | The log sequence number (LSN) of the current head of the | ||
7 | log. The LSN is exported in "cycle:basic block" format. | ||
8 | Users: xfstests | ||
9 | |||
10 | What: /sys/fs/xfs/<disk>/log/log_tail_lsn | ||
11 | Date: July 2014 | ||
12 | KernelVersion: 3.17 | ||
13 | Contact: xfs@oss.sgi.com | ||
14 | Description: | ||
15 | The log sequence number (LSN) of the current tail of the | ||
16 | log. The LSN is exported in "cycle:basic block" format. | ||
17 | |||
18 | What: /sys/fs/xfs/<disk>/log/reserve_grant_head | ||
19 | Date: July 2014 | ||
20 | KernelVersion: 3.17 | ||
21 | Contact: xfs@oss.sgi.com | ||
22 | Description: | ||
23 | The current state of the log reserve grant head. It | ||
24 | represents the total log reservation of all currently | ||
25 | outstanding transactions. The grant head is exported in | ||
26 | "cycle:bytes" format. | ||
27 | Users: xfstests | ||
28 | |||
29 | What: /sys/fs/xfs/<disk>/log/write_grant_head | ||
30 | Date: July 2014 | ||
31 | KernelVersion: 3.17 | ||
32 | Contact: xfs@oss.sgi.com | ||
33 | Description: | ||
34 | The current state of the log write grant head. It | ||
35 | represents the total log reservation of all currently | ||
36 | oustanding transactions, including regrants due to | ||
37 | rolling transactions. The grant head is exported in | ||
38 | "cycle:bytes" format. | ||
39 | Users: xfstests | ||
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 399e8cec6e60..5d47b4df61ea 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config XFS_FS | 1 | config XFS_FS |
2 | tristate "XFS filesystem support" | 2 | tristate "XFS filesystem support" |
3 | depends on BLOCK | 3 | depends on BLOCK |
4 | depends on (64BIT || LBDAF) | ||
4 | select EXPORTFS | 5 | select EXPORTFS |
5 | select LIBCRC32C | 6 | select LIBCRC32C |
6 | help | 7 | help |
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 0dfa26d626f5..d61799949580 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -86,6 +86,7 @@ xfs-y += xfs_aops.o \ | |||
86 | xfs_mru_cache.o \ | 86 | xfs_mru_cache.o \ |
87 | xfs_super.o \ | 87 | xfs_super.o \ |
88 | xfs_symlink.o \ | 88 | xfs_symlink.o \ |
89 | xfs_sysfs.o \ | ||
89 | xfs_trans.o \ | 90 | xfs_trans.o \ |
90 | xfs_xattr.o \ | 91 | xfs_xattr.o \ |
91 | kmem.o \ | 92 | kmem.o \ |
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 72a110eb1dda..de2d26d32844 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -392,7 +392,7 @@ xfs_bmap_check_leaf_extents( | |||
392 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); | 392 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); |
393 | bno = be64_to_cpu(*pp); | 393 | bno = be64_to_cpu(*pp); |
394 | 394 | ||
395 | ASSERT(bno != NULLDFSBNO); | 395 | ASSERT(bno != NULLFSBLOCK); |
396 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); | 396 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
397 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); | 397 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); |
398 | 398 | ||
@@ -1299,7 +1299,7 @@ xfs_bmap_read_extents( | |||
1299 | ASSERT(level > 0); | 1299 | ASSERT(level > 0); |
1300 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); | 1300 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); |
1301 | bno = be64_to_cpu(*pp); | 1301 | bno = be64_to_cpu(*pp); |
1302 | ASSERT(bno != NULLDFSBNO); | 1302 | ASSERT(bno != NULLFSBLOCK); |
1303 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); | 1303 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
1304 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); | 1304 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); |
1305 | /* | 1305 | /* |
@@ -1429,11 +1429,7 @@ xfs_bmap_search_multi_extents( | |||
1429 | gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; | 1429 | gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; |
1430 | gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; | 1430 | gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; |
1431 | gotp->br_state = XFS_EXT_INVALID; | 1431 | gotp->br_state = XFS_EXT_INVALID; |
1432 | #if XFS_BIG_BLKNOS | ||
1433 | gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; | 1432 | gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; |
1434 | #else | ||
1435 | gotp->br_startblock = 0xffffa5a5; | ||
1436 | #endif | ||
1437 | prevp->br_startoff = NULLFILEOFF; | 1433 | prevp->br_startoff = NULLFILEOFF; |
1438 | 1434 | ||
1439 | ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); | 1435 | ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); |
@@ -4298,8 +4294,8 @@ xfs_bmapi_delay( | |||
4298 | } | 4294 | } |
4299 | 4295 | ||
4300 | 4296 | ||
4301 | int | 4297 | static int |
4302 | __xfs_bmapi_allocate( | 4298 | xfs_bmapi_allocate( |
4303 | struct xfs_bmalloca *bma) | 4299 | struct xfs_bmalloca *bma) |
4304 | { | 4300 | { |
4305 | struct xfs_mount *mp = bma->ip->i_mount; | 4301 | struct xfs_mount *mp = bma->ip->i_mount; |
@@ -4578,9 +4574,6 @@ xfs_bmapi_write( | |||
4578 | bma.flist = flist; | 4574 | bma.flist = flist; |
4579 | bma.firstblock = firstblock; | 4575 | bma.firstblock = firstblock; |
4580 | 4576 | ||
4581 | if (flags & XFS_BMAPI_STACK_SWITCH) | ||
4582 | bma.stack_switch = 1; | ||
4583 | |||
4584 | while (bno < end && n < *nmap) { | 4577 | while (bno < end && n < *nmap) { |
4585 | inhole = eof || bma.got.br_startoff > bno; | 4578 | inhole = eof || bma.got.br_startoff > bno; |
4586 | wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); | 4579 | wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); |
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 38ba36e9b2f0..b879ca56a64c 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h | |||
@@ -77,7 +77,6 @@ typedef struct xfs_bmap_free | |||
77 | * from written to unwritten, otherwise convert from unwritten to written. | 77 | * from written to unwritten, otherwise convert from unwritten to written. |
78 | */ | 78 | */ |
79 | #define XFS_BMAPI_CONVERT 0x040 | 79 | #define XFS_BMAPI_CONVERT 0x040 |
80 | #define XFS_BMAPI_STACK_SWITCH 0x080 | ||
81 | 80 | ||
82 | #define XFS_BMAPI_FLAGS \ | 81 | #define XFS_BMAPI_FLAGS \ |
83 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ | 82 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
@@ -86,8 +85,7 @@ typedef struct xfs_bmap_free | |||
86 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ | 85 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ |
87 | { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ | 86 | { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ |
88 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ | 87 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ |
89 | { XFS_BMAPI_CONVERT, "CONVERT" }, \ | 88 | { XFS_BMAPI_CONVERT, "CONVERT" } |
90 | { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } | ||
91 | 89 | ||
92 | 90 | ||
93 | static inline int xfs_bmapi_aflag(int w) | 91 | static inline int xfs_bmapi_aflag(int w) |
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index a388de4ceaa1..fba753308f31 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c | |||
@@ -111,23 +111,8 @@ __xfs_bmbt_get_all( | |||
111 | ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); | 111 | ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); |
112 | s->br_startoff = ((xfs_fileoff_t)l0 & | 112 | s->br_startoff = ((xfs_fileoff_t)l0 & |
113 | xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; | 113 | xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; |
114 | #if XFS_BIG_BLKNOS | ||
115 | s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) | | 114 | s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) | |
116 | (((xfs_fsblock_t)l1) >> 21); | 115 | (((xfs_fsblock_t)l1) >> 21); |
117 | #else | ||
118 | #ifdef DEBUG | ||
119 | { | ||
120 | xfs_dfsbno_t b; | ||
121 | |||
122 | b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) | | ||
123 | (((xfs_dfsbno_t)l1) >> 21); | ||
124 | ASSERT((b >> 32) == 0 || isnulldstartblock(b)); | ||
125 | s->br_startblock = (xfs_fsblock_t)b; | ||
126 | } | ||
127 | #else /* !DEBUG */ | ||
128 | s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21); | ||
129 | #endif /* DEBUG */ | ||
130 | #endif /* XFS_BIG_BLKNOS */ | ||
131 | s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21)); | 116 | s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21)); |
132 | /* This is xfs_extent_state() in-line */ | 117 | /* This is xfs_extent_state() in-line */ |
133 | if (ext_flag) { | 118 | if (ext_flag) { |
@@ -163,21 +148,8 @@ xfs_fsblock_t | |||
163 | xfs_bmbt_get_startblock( | 148 | xfs_bmbt_get_startblock( |
164 | xfs_bmbt_rec_host_t *r) | 149 | xfs_bmbt_rec_host_t *r) |
165 | { | 150 | { |
166 | #if XFS_BIG_BLKNOS | ||
167 | return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) | | 151 | return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) | |
168 | (((xfs_fsblock_t)r->l1) >> 21); | 152 | (((xfs_fsblock_t)r->l1) >> 21); |
169 | #else | ||
170 | #ifdef DEBUG | ||
171 | xfs_dfsbno_t b; | ||
172 | |||
173 | b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) | | ||
174 | (((xfs_dfsbno_t)r->l1) >> 21); | ||
175 | ASSERT((b >> 32) == 0 || isnulldstartblock(b)); | ||
176 | return (xfs_fsblock_t)b; | ||
177 | #else /* !DEBUG */ | ||
178 | return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); | ||
179 | #endif /* DEBUG */ | ||
180 | #endif /* XFS_BIG_BLKNOS */ | ||
181 | } | 153 | } |
182 | 154 | ||
183 | /* | 155 | /* |
@@ -241,7 +213,6 @@ xfs_bmbt_set_allf( | |||
241 | ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); | 213 | ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); |
242 | ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | 214 | ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); |
243 | 215 | ||
244 | #if XFS_BIG_BLKNOS | ||
245 | ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); | 216 | ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); |
246 | 217 | ||
247 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 218 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
@@ -250,23 +221,6 @@ xfs_bmbt_set_allf( | |||
250 | r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | | 221 | r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | |
251 | ((xfs_bmbt_rec_base_t)blockcount & | 222 | ((xfs_bmbt_rec_base_t)blockcount & |
252 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); | 223 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); |
253 | #else /* !XFS_BIG_BLKNOS */ | ||
254 | if (isnullstartblock(startblock)) { | ||
255 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
256 | ((xfs_bmbt_rec_base_t)startoff << 9) | | ||
257 | (xfs_bmbt_rec_base_t)xfs_mask64lo(9); | ||
258 | r->l1 = xfs_mask64hi(11) | | ||
259 | ((xfs_bmbt_rec_base_t)startblock << 21) | | ||
260 | ((xfs_bmbt_rec_base_t)blockcount & | ||
261 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); | ||
262 | } else { | ||
263 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
264 | ((xfs_bmbt_rec_base_t)startoff << 9); | ||
265 | r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | | ||
266 | ((xfs_bmbt_rec_base_t)blockcount & | ||
267 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); | ||
268 | } | ||
269 | #endif /* XFS_BIG_BLKNOS */ | ||
270 | } | 224 | } |
271 | 225 | ||
272 | /* | 226 | /* |
@@ -298,8 +252,6 @@ xfs_bmbt_disk_set_allf( | |||
298 | ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); | 252 | ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); |
299 | ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); | 253 | ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); |
300 | ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | 254 | ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); |
301 | |||
302 | #if XFS_BIG_BLKNOS | ||
303 | ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); | 255 | ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); |
304 | 256 | ||
305 | r->l0 = cpu_to_be64( | 257 | r->l0 = cpu_to_be64( |
@@ -310,26 +262,6 @@ xfs_bmbt_disk_set_allf( | |||
310 | ((xfs_bmbt_rec_base_t)startblock << 21) | | 262 | ((xfs_bmbt_rec_base_t)startblock << 21) | |
311 | ((xfs_bmbt_rec_base_t)blockcount & | 263 | ((xfs_bmbt_rec_base_t)blockcount & |
312 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); | 264 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); |
313 | #else /* !XFS_BIG_BLKNOS */ | ||
314 | if (isnullstartblock(startblock)) { | ||
315 | r->l0 = cpu_to_be64( | ||
316 | ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
317 | ((xfs_bmbt_rec_base_t)startoff << 9) | | ||
318 | (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); | ||
319 | r->l1 = cpu_to_be64(xfs_mask64hi(11) | | ||
320 | ((xfs_bmbt_rec_base_t)startblock << 21) | | ||
321 | ((xfs_bmbt_rec_base_t)blockcount & | ||
322 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); | ||
323 | } else { | ||
324 | r->l0 = cpu_to_be64( | ||
325 | ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
326 | ((xfs_bmbt_rec_base_t)startoff << 9)); | ||
327 | r->l1 = cpu_to_be64( | ||
328 | ((xfs_bmbt_rec_base_t)startblock << 21) | | ||
329 | ((xfs_bmbt_rec_base_t)blockcount & | ||
330 | (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); | ||
331 | } | ||
332 | #endif /* XFS_BIG_BLKNOS */ | ||
333 | } | 265 | } |
334 | 266 | ||
335 | /* | 267 | /* |
@@ -365,24 +297,11 @@ xfs_bmbt_set_startblock( | |||
365 | xfs_bmbt_rec_host_t *r, | 297 | xfs_bmbt_rec_host_t *r, |
366 | xfs_fsblock_t v) | 298 | xfs_fsblock_t v) |
367 | { | 299 | { |
368 | #if XFS_BIG_BLKNOS | ||
369 | ASSERT((v & xfs_mask64hi(12)) == 0); | 300 | ASSERT((v & xfs_mask64hi(12)) == 0); |
370 | r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) | | 301 | r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) | |
371 | (xfs_bmbt_rec_base_t)(v >> 43); | 302 | (xfs_bmbt_rec_base_t)(v >> 43); |
372 | r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | | 303 | r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | |
373 | (xfs_bmbt_rec_base_t)(v << 21); | 304 | (xfs_bmbt_rec_base_t)(v << 21); |
374 | #else /* !XFS_BIG_BLKNOS */ | ||
375 | if (isnullstartblock(v)) { | ||
376 | r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9); | ||
377 | r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) | | ||
378 | ((xfs_bmbt_rec_base_t)v << 21) | | ||
379 | (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); | ||
380 | } else { | ||
381 | r->l0 &= ~(xfs_bmbt_rec_base_t)xfs_mask64lo(9); | ||
382 | r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | | ||
383 | (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); | ||
384 | } | ||
385 | #endif /* XFS_BIG_BLKNOS */ | ||
386 | } | 305 | } |
387 | 306 | ||
388 | /* | 307 | /* |
@@ -438,8 +357,8 @@ xfs_bmbt_to_bmdr( | |||
438 | cpu_to_be64(XFS_BUF_DADDR_NULL)); | 357 | cpu_to_be64(XFS_BUF_DADDR_NULL)); |
439 | } else | 358 | } else |
440 | ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC)); | 359 | ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC)); |
441 | ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO)); | 360 | ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK)); |
442 | ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO)); | 361 | ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK)); |
443 | ASSERT(rblock->bb_level != 0); | 362 | ASSERT(rblock->bb_level != 0); |
444 | dblock->bb_level = rblock->bb_level; | 363 | dblock->bb_level = rblock->bb_level; |
445 | dblock->bb_numrecs = rblock->bb_numrecs; | 364 | dblock->bb_numrecs = rblock->bb_numrecs; |
@@ -763,11 +682,11 @@ xfs_bmbt_verify( | |||
763 | 682 | ||
764 | /* sibling pointer verification */ | 683 | /* sibling pointer verification */ |
765 | if (!block->bb_u.l.bb_leftsib || | 684 | if (!block->bb_u.l.bb_leftsib || |
766 | (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLDFSBNO) && | 685 | (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) && |
767 | !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))) | 686 | !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))) |
768 | return false; | 687 | return false; |
769 | if (!block->bb_u.l.bb_rightsib || | 688 | if (!block->bb_u.l.bb_rightsib || |
770 | (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLDFSBNO) && | 689 | (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) && |
771 | !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))) | 690 | !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))) |
772 | return false; | 691 | return false; |
773 | 692 | ||
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 0097c42f1f10..8fe6a93ff473 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "xfs_error.h" | 33 | #include "xfs_error.h" |
34 | #include "xfs_trace.h" | 34 | #include "xfs_trace.h" |
35 | #include "xfs_cksum.h" | 35 | #include "xfs_cksum.h" |
36 | #include "xfs_alloc.h" | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Cursor allocation zone. | 39 | * Cursor allocation zone. |
@@ -77,11 +78,11 @@ xfs_btree_check_lblock( | |||
77 | be16_to_cpu(block->bb_numrecs) <= | 78 | be16_to_cpu(block->bb_numrecs) <= |
78 | cur->bc_ops->get_maxrecs(cur, level) && | 79 | cur->bc_ops->get_maxrecs(cur, level) && |
79 | block->bb_u.l.bb_leftsib && | 80 | block->bb_u.l.bb_leftsib && |
80 | (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO) || | 81 | (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK) || |
81 | XFS_FSB_SANITY_CHECK(mp, | 82 | XFS_FSB_SANITY_CHECK(mp, |
82 | be64_to_cpu(block->bb_u.l.bb_leftsib))) && | 83 | be64_to_cpu(block->bb_u.l.bb_leftsib))) && |
83 | block->bb_u.l.bb_rightsib && | 84 | block->bb_u.l.bb_rightsib && |
84 | (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO) || | 85 | (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK) || |
85 | XFS_FSB_SANITY_CHECK(mp, | 86 | XFS_FSB_SANITY_CHECK(mp, |
86 | be64_to_cpu(block->bb_u.l.bb_rightsib))); | 87 | be64_to_cpu(block->bb_u.l.bb_rightsib))); |
87 | 88 | ||
@@ -166,12 +167,12 @@ xfs_btree_check_block( | |||
166 | int /* error (0 or EFSCORRUPTED) */ | 167 | int /* error (0 or EFSCORRUPTED) */ |
167 | xfs_btree_check_lptr( | 168 | xfs_btree_check_lptr( |
168 | struct xfs_btree_cur *cur, /* btree cursor */ | 169 | struct xfs_btree_cur *cur, /* btree cursor */ |
169 | xfs_dfsbno_t bno, /* btree block disk address */ | 170 | xfs_fsblock_t bno, /* btree block disk address */ |
170 | int level) /* btree block level */ | 171 | int level) /* btree block level */ |
171 | { | 172 | { |
172 | XFS_WANT_CORRUPTED_RETURN( | 173 | XFS_WANT_CORRUPTED_RETURN( |
173 | level > 0 && | 174 | level > 0 && |
174 | bno != NULLDFSBNO && | 175 | bno != NULLFSBLOCK && |
175 | XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); | 176 | XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); |
176 | return 0; | 177 | return 0; |
177 | } | 178 | } |
@@ -594,7 +595,7 @@ xfs_btree_islastblock( | |||
594 | block = xfs_btree_get_block(cur, level, &bp); | 595 | block = xfs_btree_get_block(cur, level, &bp); |
595 | xfs_btree_check_block(cur, block, level, bp); | 596 | xfs_btree_check_block(cur, block, level, bp); |
596 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) | 597 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
597 | return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO); | 598 | return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); |
598 | else | 599 | else |
599 | return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); | 600 | return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); |
600 | } | 601 | } |
@@ -770,16 +771,16 @@ xfs_btree_readahead_lblock( | |||
770 | struct xfs_btree_block *block) | 771 | struct xfs_btree_block *block) |
771 | { | 772 | { |
772 | int rval = 0; | 773 | int rval = 0; |
773 | xfs_dfsbno_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); | 774 | xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); |
774 | xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); | 775 | xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); |
775 | 776 | ||
776 | if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { | 777 | if ((lr & XFS_BTCUR_LEFTRA) && left != NULLFSBLOCK) { |
777 | xfs_btree_reada_bufl(cur->bc_mp, left, 1, | 778 | xfs_btree_reada_bufl(cur->bc_mp, left, 1, |
778 | cur->bc_ops->buf_ops); | 779 | cur->bc_ops->buf_ops); |
779 | rval++; | 780 | rval++; |
780 | } | 781 | } |
781 | 782 | ||
782 | if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { | 783 | if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLFSBLOCK) { |
783 | xfs_btree_reada_bufl(cur->bc_mp, right, 1, | 784 | xfs_btree_reada_bufl(cur->bc_mp, right, 1, |
784 | cur->bc_ops->buf_ops); | 785 | cur->bc_ops->buf_ops); |
785 | rval++; | 786 | rval++; |
@@ -851,7 +852,7 @@ xfs_btree_ptr_to_daddr( | |||
851 | union xfs_btree_ptr *ptr) | 852 | union xfs_btree_ptr *ptr) |
852 | { | 853 | { |
853 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { | 854 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { |
854 | ASSERT(ptr->l != cpu_to_be64(NULLDFSBNO)); | 855 | ASSERT(ptr->l != cpu_to_be64(NULLFSBLOCK)); |
855 | 856 | ||
856 | return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); | 857 | return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); |
857 | } else { | 858 | } else { |
@@ -899,9 +900,9 @@ xfs_btree_setbuf( | |||
899 | 900 | ||
900 | b = XFS_BUF_TO_BLOCK(bp); | 901 | b = XFS_BUF_TO_BLOCK(bp); |
901 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { | 902 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { |
902 | if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO)) | 903 | if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK)) |
903 | cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; | 904 | cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; |
904 | if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO)) | 905 | if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK)) |
905 | cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; | 906 | cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; |
906 | } else { | 907 | } else { |
907 | if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK)) | 908 | if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK)) |
@@ -917,7 +918,7 @@ xfs_btree_ptr_is_null( | |||
917 | union xfs_btree_ptr *ptr) | 918 | union xfs_btree_ptr *ptr) |
918 | { | 919 | { |
919 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) | 920 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
920 | return ptr->l == cpu_to_be64(NULLDFSBNO); | 921 | return ptr->l == cpu_to_be64(NULLFSBLOCK); |
921 | else | 922 | else |
922 | return ptr->s == cpu_to_be32(NULLAGBLOCK); | 923 | return ptr->s == cpu_to_be32(NULLAGBLOCK); |
923 | } | 924 | } |
@@ -928,7 +929,7 @@ xfs_btree_set_ptr_null( | |||
928 | union xfs_btree_ptr *ptr) | 929 | union xfs_btree_ptr *ptr) |
929 | { | 930 | { |
930 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) | 931 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
931 | ptr->l = cpu_to_be64(NULLDFSBNO); | 932 | ptr->l = cpu_to_be64(NULLFSBLOCK); |
932 | else | 933 | else |
933 | ptr->s = cpu_to_be32(NULLAGBLOCK); | 934 | ptr->s = cpu_to_be32(NULLAGBLOCK); |
934 | } | 935 | } |
@@ -996,8 +997,8 @@ xfs_btree_init_block_int( | |||
996 | buf->bb_numrecs = cpu_to_be16(numrecs); | 997 | buf->bb_numrecs = cpu_to_be16(numrecs); |
997 | 998 | ||
998 | if (flags & XFS_BTREE_LONG_PTRS) { | 999 | if (flags & XFS_BTREE_LONG_PTRS) { |
999 | buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); | 1000 | buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK); |
1000 | buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); | 1001 | buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK); |
1001 | if (flags & XFS_BTREE_CRC_BLOCKS) { | 1002 | if (flags & XFS_BTREE_CRC_BLOCKS) { |
1002 | buf->bb_u.l.bb_blkno = cpu_to_be64(blkno); | 1003 | buf->bb_u.l.bb_blkno = cpu_to_be64(blkno); |
1003 | buf->bb_u.l.bb_owner = cpu_to_be64(owner); | 1004 | buf->bb_u.l.bb_owner = cpu_to_be64(owner); |
@@ -2323,7 +2324,7 @@ error1: | |||
2323 | * record (to be inserted into parent). | 2324 | * record (to be inserted into parent). |
2324 | */ | 2325 | */ |
2325 | STATIC int /* error */ | 2326 | STATIC int /* error */ |
2326 | xfs_btree_split( | 2327 | __xfs_btree_split( |
2327 | struct xfs_btree_cur *cur, | 2328 | struct xfs_btree_cur *cur, |
2328 | int level, | 2329 | int level, |
2329 | union xfs_btree_ptr *ptrp, | 2330 | union xfs_btree_ptr *ptrp, |
@@ -2503,6 +2504,85 @@ error0: | |||
2503 | return error; | 2504 | return error; |
2504 | } | 2505 | } |
2505 | 2506 | ||
2507 | struct xfs_btree_split_args { | ||
2508 | struct xfs_btree_cur *cur; | ||
2509 | int level; | ||
2510 | union xfs_btree_ptr *ptrp; | ||
2511 | union xfs_btree_key *key; | ||
2512 | struct xfs_btree_cur **curp; | ||
2513 | int *stat; /* success/failure */ | ||
2514 | int result; | ||
2515 | bool kswapd; /* allocation in kswapd context */ | ||
2516 | struct completion *done; | ||
2517 | struct work_struct work; | ||
2518 | }; | ||
2519 | |||
2520 | /* | ||
2521 | * Stack switching interfaces for allocation | ||
2522 | */ | ||
2523 | static void | ||
2524 | xfs_btree_split_worker( | ||
2525 | struct work_struct *work) | ||
2526 | { | ||
2527 | struct xfs_btree_split_args *args = container_of(work, | ||
2528 | struct xfs_btree_split_args, work); | ||
2529 | unsigned long pflags; | ||
2530 | unsigned long new_pflags = PF_FSTRANS; | ||
2531 | |||
2532 | /* | ||
2533 | * we are in a transaction context here, but may also be doing work | ||
2534 | * in kswapd context, and hence we may need to inherit that state | ||
2535 | * temporarily to ensure that we don't block waiting for memory reclaim | ||
2536 | * in any way. | ||
2537 | */ | ||
2538 | if (args->kswapd) | ||
2539 | new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; | ||
2540 | |||
2541 | current_set_flags_nested(&pflags, new_pflags); | ||
2542 | |||
2543 | args->result = __xfs_btree_split(args->cur, args->level, args->ptrp, | ||
2544 | args->key, args->curp, args->stat); | ||
2545 | complete(args->done); | ||
2546 | |||
2547 | current_restore_flags_nested(&pflags, new_pflags); | ||
2548 | } | ||
2549 | |||
2550 | /* | ||
2551 | * BMBT split requests often come in with little stack to work on. Push | ||
2552 | * them off to a worker thread so there is lots of stack to use. For the other | ||
2553 | * btree types, just call directly to avoid the context switch overhead here. | ||
2554 | */ | ||
2555 | STATIC int /* error */ | ||
2556 | xfs_btree_split( | ||
2557 | struct xfs_btree_cur *cur, | ||
2558 | int level, | ||
2559 | union xfs_btree_ptr *ptrp, | ||
2560 | union xfs_btree_key *key, | ||
2561 | struct xfs_btree_cur **curp, | ||
2562 | int *stat) /* success/failure */ | ||
2563 | { | ||
2564 | struct xfs_btree_split_args args; | ||
2565 | DECLARE_COMPLETION_ONSTACK(done); | ||
2566 | |||
2567 | if (cur->bc_btnum != XFS_BTNUM_BMAP) | ||
2568 | return __xfs_btree_split(cur, level, ptrp, key, curp, stat); | ||
2569 | |||
2570 | args.cur = cur; | ||
2571 | args.level = level; | ||
2572 | args.ptrp = ptrp; | ||
2573 | args.key = key; | ||
2574 | args.curp = curp; | ||
2575 | args.stat = stat; | ||
2576 | args.done = &done; | ||
2577 | args.kswapd = current_is_kswapd(); | ||
2578 | INIT_WORK_ONSTACK(&args.work, xfs_btree_split_worker); | ||
2579 | queue_work(xfs_alloc_wq, &args.work); | ||
2580 | wait_for_completion(&done); | ||
2581 | destroy_work_on_stack(&args.work); | ||
2582 | return args.result; | ||
2583 | } | ||
2584 | |||
2585 | |||
2506 | /* | 2586 | /* |
2507 | * Copy the old inode root contents into a real block and make the | 2587 | * Copy the old inode root contents into a real block and make the |
2508 | * broot point to it. | 2588 | * broot point to it. |
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index a04b69422f67..8f18bab73ea5 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h | |||
@@ -258,7 +258,7 @@ xfs_btree_check_block( | |||
258 | int /* error (0 or EFSCORRUPTED) */ | 258 | int /* error (0 or EFSCORRUPTED) */ |
259 | xfs_btree_check_lptr( | 259 | xfs_btree_check_lptr( |
260 | struct xfs_btree_cur *cur, /* btree cursor */ | 260 | struct xfs_btree_cur *cur, /* btree cursor */ |
261 | xfs_dfsbno_t ptr, /* btree block disk address */ | 261 | xfs_fsblock_t ptr, /* btree block disk address */ |
262 | int level); /* btree block level */ | 262 | int level); /* btree block level */ |
263 | 263 | ||
264 | /* | 264 | /* |
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 8d809873525b..2c42ae28d027 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c | |||
@@ -2004,7 +2004,7 @@ xfs_da_grow_inode_int( | |||
2004 | struct xfs_trans *tp = args->trans; | 2004 | struct xfs_trans *tp = args->trans; |
2005 | struct xfs_inode *dp = args->dp; | 2005 | struct xfs_inode *dp = args->dp; |
2006 | int w = args->whichfork; | 2006 | int w = args->whichfork; |
2007 | xfs_drfsbno_t nblks = dp->i_d.di_nblocks; | 2007 | xfs_rfsblock_t nblks = dp->i_d.di_nblocks; |
2008 | struct xfs_bmbt_irec map, *mapp; | 2008 | struct xfs_bmbt_irec map, *mapp; |
2009 | int nmap, error, got, i, mapi; | 2009 | int nmap, error, got, i, mapi; |
2010 | 2010 | ||
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 8f4f26af35e1..5079e051ef08 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c | |||
@@ -51,10 +51,9 @@ static void xfs_dir2_sf_check(xfs_da_args_t *args); | |||
51 | #else | 51 | #else |
52 | #define xfs_dir2_sf_check(args) | 52 | #define xfs_dir2_sf_check(args) |
53 | #endif /* DEBUG */ | 53 | #endif /* DEBUG */ |
54 | #if XFS_BIG_INUMS | 54 | |
55 | static void xfs_dir2_sf_toino4(xfs_da_args_t *args); | 55 | static void xfs_dir2_sf_toino4(xfs_da_args_t *args); |
56 | static void xfs_dir2_sf_toino8(xfs_da_args_t *args); | 56 | static void xfs_dir2_sf_toino8(xfs_da_args_t *args); |
57 | #endif /* XFS_BIG_INUMS */ | ||
58 | 57 | ||
59 | /* | 58 | /* |
60 | * Given a block directory (dp/block), calculate its size as a shortform (sf) | 59 | * Given a block directory (dp/block), calculate its size as a shortform (sf) |
@@ -117,10 +116,10 @@ xfs_dir2_block_sfsize( | |||
117 | isdotdot = | 116 | isdotdot = |
118 | dep->namelen == 2 && | 117 | dep->namelen == 2 && |
119 | dep->name[0] == '.' && dep->name[1] == '.'; | 118 | dep->name[0] == '.' && dep->name[1] == '.'; |
120 | #if XFS_BIG_INUMS | 119 | |
121 | if (!isdot) | 120 | if (!isdot) |
122 | i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; | 121 | i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; |
123 | #endif | 122 | |
124 | /* take into account the file type field */ | 123 | /* take into account the file type field */ |
125 | if (!isdot && !isdotdot) { | 124 | if (!isdot && !isdotdot) { |
126 | count++; | 125 | count++; |
@@ -318,7 +317,7 @@ xfs_dir2_sf_addname( | |||
318 | */ | 317 | */ |
319 | incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen); | 318 | incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen); |
320 | objchange = 0; | 319 | objchange = 0; |
321 | #if XFS_BIG_INUMS | 320 | |
322 | /* | 321 | /* |
323 | * Do we have to change to 8 byte inodes? | 322 | * Do we have to change to 8 byte inodes? |
324 | */ | 323 | */ |
@@ -332,7 +331,7 @@ xfs_dir2_sf_addname( | |||
332 | (uint)sizeof(xfs_dir2_ino4_t)); | 331 | (uint)sizeof(xfs_dir2_ino4_t)); |
333 | objchange = 1; | 332 | objchange = 1; |
334 | } | 333 | } |
335 | #endif | 334 | |
336 | new_isize = (int)dp->i_d.di_size + incr_isize; | 335 | new_isize = (int)dp->i_d.di_size + incr_isize; |
337 | /* | 336 | /* |
338 | * Won't fit as shortform any more (due to size), | 337 | * Won't fit as shortform any more (due to size), |
@@ -370,10 +369,8 @@ xfs_dir2_sf_addname( | |||
370 | */ | 369 | */ |
371 | else { | 370 | else { |
372 | ASSERT(pick == 2); | 371 | ASSERT(pick == 2); |
373 | #if XFS_BIG_INUMS | ||
374 | if (objchange) | 372 | if (objchange) |
375 | xfs_dir2_sf_toino8(args); | 373 | xfs_dir2_sf_toino8(args); |
376 | #endif | ||
377 | xfs_dir2_sf_addname_hard(args, objchange, new_isize); | 374 | xfs_dir2_sf_addname_hard(args, objchange, new_isize); |
378 | } | 375 | } |
379 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | 376 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); |
@@ -425,10 +422,8 @@ xfs_dir2_sf_addname_easy( | |||
425 | * Update the header and inode. | 422 | * Update the header and inode. |
426 | */ | 423 | */ |
427 | sfp->count++; | 424 | sfp->count++; |
428 | #if XFS_BIG_INUMS | ||
429 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) | 425 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) |
430 | sfp->i8count++; | 426 | sfp->i8count++; |
431 | #endif | ||
432 | dp->i_d.di_size = new_isize; | 427 | dp->i_d.di_size = new_isize; |
433 | xfs_dir2_sf_check(args); | 428 | xfs_dir2_sf_check(args); |
434 | } | 429 | } |
@@ -516,10 +511,8 @@ xfs_dir2_sf_addname_hard( | |||
516 | dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); | 511 | dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); |
517 | dp->d_ops->sf_put_ftype(sfep, args->filetype); | 512 | dp->d_ops->sf_put_ftype(sfep, args->filetype); |
518 | sfp->count++; | 513 | sfp->count++; |
519 | #if XFS_BIG_INUMS | ||
520 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) | 514 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) |
521 | sfp->i8count++; | 515 | sfp->i8count++; |
522 | #endif | ||
523 | /* | 516 | /* |
524 | * If there's more left to copy, do that. | 517 | * If there's more left to copy, do that. |
525 | */ | 518 | */ |
@@ -593,13 +586,8 @@ xfs_dir2_sf_addname_pick( | |||
593 | /* | 586 | /* |
594 | * If changing the inode number size, do it the hard way. | 587 | * If changing the inode number size, do it the hard way. |
595 | */ | 588 | */ |
596 | #if XFS_BIG_INUMS | 589 | if (objchange) |
597 | if (objchange) { | ||
598 | return 2; | 590 | return 2; |
599 | } | ||
600 | #else | ||
601 | ASSERT(objchange == 0); | ||
602 | #endif | ||
603 | /* | 591 | /* |
604 | * If it won't fit at the end then do it the hard way (use the hole). | 592 | * If it won't fit at the end then do it the hard way (use the hole). |
605 | */ | 593 | */ |
@@ -650,7 +638,6 @@ xfs_dir2_sf_check( | |||
650 | ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); | 638 | ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); |
651 | } | 639 | } |
652 | ASSERT(i8count == sfp->i8count); | 640 | ASSERT(i8count == sfp->i8count); |
653 | ASSERT(XFS_BIG_INUMS || i8count == 0); | ||
654 | ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); | 641 | ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); |
655 | ASSERT(offset + | 642 | ASSERT(offset + |
656 | (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + | 643 | (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + |
@@ -870,7 +857,6 @@ xfs_dir2_sf_removename( | |||
870 | */ | 857 | */ |
871 | xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); | 858 | xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); |
872 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 859 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
873 | #if XFS_BIG_INUMS | ||
874 | /* | 860 | /* |
875 | * Are we changing inode number size? | 861 | * Are we changing inode number size? |
876 | */ | 862 | */ |
@@ -880,7 +866,6 @@ xfs_dir2_sf_removename( | |||
880 | else | 866 | else |
881 | sfp->i8count--; | 867 | sfp->i8count--; |
882 | } | 868 | } |
883 | #endif | ||
884 | xfs_dir2_sf_check(args); | 869 | xfs_dir2_sf_check(args); |
885 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | 870 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); |
886 | return 0; | 871 | return 0; |
@@ -895,12 +880,8 @@ xfs_dir2_sf_replace( | |||
895 | { | 880 | { |
896 | xfs_inode_t *dp; /* incore directory inode */ | 881 | xfs_inode_t *dp; /* incore directory inode */ |
897 | int i; /* entry index */ | 882 | int i; /* entry index */ |
898 | #if XFS_BIG_INUMS || defined(DEBUG) | ||
899 | xfs_ino_t ino=0; /* entry old inode number */ | 883 | xfs_ino_t ino=0; /* entry old inode number */ |
900 | #endif | ||
901 | #if XFS_BIG_INUMS | ||
902 | int i8elevated; /* sf_toino8 set i8count=1 */ | 884 | int i8elevated; /* sf_toino8 set i8count=1 */ |
903 | #endif | ||
904 | xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ | 885 | xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ |
905 | xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ | 886 | xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ |
906 | 887 | ||
@@ -920,7 +901,7 @@ xfs_dir2_sf_replace( | |||
920 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 901 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
921 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 902 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
922 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); | 903 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); |
923 | #if XFS_BIG_INUMS | 904 | |
924 | /* | 905 | /* |
925 | * New inode number is large, and need to convert to 8-byte inodes. | 906 | * New inode number is large, and need to convert to 8-byte inodes. |
926 | */ | 907 | */ |
@@ -951,17 +932,15 @@ xfs_dir2_sf_replace( | |||
951 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 932 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
952 | } else | 933 | } else |
953 | i8elevated = 0; | 934 | i8elevated = 0; |
954 | #endif | 935 | |
955 | ASSERT(args->namelen != 1 || args->name[0] != '.'); | 936 | ASSERT(args->namelen != 1 || args->name[0] != '.'); |
956 | /* | 937 | /* |
957 | * Replace ..'s entry. | 938 | * Replace ..'s entry. |
958 | */ | 939 | */ |
959 | if (args->namelen == 2 && | 940 | if (args->namelen == 2 && |
960 | args->name[0] == '.' && args->name[1] == '.') { | 941 | args->name[0] == '.' && args->name[1] == '.') { |
961 | #if XFS_BIG_INUMS || defined(DEBUG) | ||
962 | ino = dp->d_ops->sf_get_parent_ino(sfp); | 942 | ino = dp->d_ops->sf_get_parent_ino(sfp); |
963 | ASSERT(args->inumber != ino); | 943 | ASSERT(args->inumber != ino); |
964 | #endif | ||
965 | dp->d_ops->sf_put_parent_ino(sfp, args->inumber); | 944 | dp->d_ops->sf_put_parent_ino(sfp, args->inumber); |
966 | } | 945 | } |
967 | /* | 946 | /* |
@@ -972,10 +951,8 @@ xfs_dir2_sf_replace( | |||
972 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { | 951 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
973 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == | 952 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == |
974 | XFS_CMP_EXACT) { | 953 | XFS_CMP_EXACT) { |
975 | #if XFS_BIG_INUMS || defined(DEBUG) | ||
976 | ino = dp->d_ops->sf_get_ino(sfp, sfep); | 954 | ino = dp->d_ops->sf_get_ino(sfp, sfep); |
977 | ASSERT(args->inumber != ino); | 955 | ASSERT(args->inumber != ino); |
978 | #endif | ||
979 | dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); | 956 | dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); |
980 | dp->d_ops->sf_put_ftype(sfep, args->filetype); | 957 | dp->d_ops->sf_put_ftype(sfep, args->filetype); |
981 | break; | 958 | break; |
@@ -986,14 +963,11 @@ xfs_dir2_sf_replace( | |||
986 | */ | 963 | */ |
987 | if (i == sfp->count) { | 964 | if (i == sfp->count) { |
988 | ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); | 965 | ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); |
989 | #if XFS_BIG_INUMS | ||
990 | if (i8elevated) | 966 | if (i8elevated) |
991 | xfs_dir2_sf_toino4(args); | 967 | xfs_dir2_sf_toino4(args); |
992 | #endif | ||
993 | return -ENOENT; | 968 | return -ENOENT; |
994 | } | 969 | } |
995 | } | 970 | } |
996 | #if XFS_BIG_INUMS | ||
997 | /* | 971 | /* |
998 | * See if the old number was large, the new number is small. | 972 | * See if the old number was large, the new number is small. |
999 | */ | 973 | */ |
@@ -1020,13 +994,11 @@ xfs_dir2_sf_replace( | |||
1020 | if (!i8elevated) | 994 | if (!i8elevated) |
1021 | sfp->i8count++; | 995 | sfp->i8count++; |
1022 | } | 996 | } |
1023 | #endif | ||
1024 | xfs_dir2_sf_check(args); | 997 | xfs_dir2_sf_check(args); |
1025 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); | 998 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); |
1026 | return 0; | 999 | return 0; |
1027 | } | 1000 | } |
1028 | 1001 | ||
1029 | #if XFS_BIG_INUMS | ||
1030 | /* | 1002 | /* |
1031 | * Convert from 8-byte inode numbers to 4-byte inode numbers. | 1003 | * Convert from 8-byte inode numbers to 4-byte inode numbers. |
1032 | * The last 8-byte inode number is gone, but the count is still 1. | 1004 | * The last 8-byte inode number is gone, but the count is still 1. |
@@ -1181,4 +1153,3 @@ xfs_dir2_sf_toino8( | |||
1181 | dp->i_d.di_size = newsize; | 1153 | dp->i_d.di_size = newsize; |
1182 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | 1154 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); |
1183 | } | 1155 | } |
1184 | #endif /* XFS_BIG_INUMS */ | ||
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 34d85aca3058..7e42bba9a420 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h | |||
@@ -68,11 +68,7 @@ struct xfs_ifork; | |||
68 | #define XFS_RTLOBIT(w) xfs_lowbit32(w) | 68 | #define XFS_RTLOBIT(w) xfs_lowbit32(w) |
69 | #define XFS_RTHIBIT(w) xfs_highbit32(w) | 69 | #define XFS_RTHIBIT(w) xfs_highbit32(w) |
70 | 70 | ||
71 | #if XFS_BIG_BLKNOS | ||
72 | #define XFS_RTBLOCKLOG(b) xfs_highbit64(b) | 71 | #define XFS_RTBLOCKLOG(b) xfs_highbit64(b) |
73 | #else | ||
74 | #define XFS_RTBLOCKLOG(b) xfs_highbit32(b) | ||
75 | #endif | ||
76 | 72 | ||
77 | /* | 73 | /* |
78 | * Dquot and dquot block format definitions | 74 | * Dquot and dquot block format definitions |
@@ -304,23 +300,15 @@ typedef struct xfs_bmbt_rec_host { | |||
304 | * Values and macros for delayed-allocation startblock fields. | 300 | * Values and macros for delayed-allocation startblock fields. |
305 | */ | 301 | */ |
306 | #define STARTBLOCKVALBITS 17 | 302 | #define STARTBLOCKVALBITS 17 |
307 | #define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) | 303 | #define STARTBLOCKMASKBITS (15 + 20) |
308 | #define DSTARTBLOCKMASKBITS (15 + 20) | ||
309 | #define STARTBLOCKMASK \ | 304 | #define STARTBLOCKMASK \ |
310 | (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) | 305 | (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) |
311 | #define DSTARTBLOCKMASK \ | ||
312 | (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) | ||
313 | 306 | ||
314 | static inline int isnullstartblock(xfs_fsblock_t x) | 307 | static inline int isnullstartblock(xfs_fsblock_t x) |
315 | { | 308 | { |
316 | return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; | 309 | return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; |
317 | } | 310 | } |
318 | 311 | ||
319 | static inline int isnulldstartblock(xfs_dfsbno_t x) | ||
320 | { | ||
321 | return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; | ||
322 | } | ||
323 | |||
324 | static inline xfs_fsblock_t nullstartblock(int k) | 312 | static inline xfs_fsblock_t nullstartblock(int k) |
325 | { | 313 | { |
326 | ASSERT(k < (1 << STARTBLOCKVALBITS)); | 314 | ASSERT(k < (1 << STARTBLOCKVALBITS)); |
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 8ac9411bcf2a..6a00f7fed69d 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c | |||
@@ -528,7 +528,7 @@ xfs_iroot_realloc( | |||
528 | ifp->if_broot_bytes = (int)new_size; | 528 | ifp->if_broot_bytes = (int)new_size; |
529 | ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= | 529 | ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= |
530 | XFS_IFORK_SIZE(ip, whichfork)); | 530 | XFS_IFORK_SIZE(ip, whichfork)); |
531 | memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); | 531 | memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t)); |
532 | return; | 532 | return; |
533 | } | 533 | } |
534 | 534 | ||
@@ -575,7 +575,7 @@ xfs_iroot_realloc( | |||
575 | ifp->if_broot_bytes); | 575 | ifp->if_broot_bytes); |
576 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, | 576 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, |
577 | (int)new_size); | 577 | (int)new_size); |
578 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); | 578 | memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t)); |
579 | } | 579 | } |
580 | kmem_free(ifp->if_broot); | 580 | kmem_free(ifp->if_broot); |
581 | ifp->if_broot = new_broot; | 581 | ifp->if_broot = new_broot; |
diff --git a/fs/xfs/libxfs/xfs_inum.h b/fs/xfs/libxfs/xfs_inum.h index 90efdaf1706f..4ff2278e147a 100644 --- a/fs/xfs/libxfs/xfs_inum.h +++ b/fs/xfs/libxfs/xfs_inum.h | |||
@@ -54,11 +54,7 @@ struct xfs_mount; | |||
54 | #define XFS_OFFBNO_TO_AGINO(mp,b,o) \ | 54 | #define XFS_OFFBNO_TO_AGINO(mp,b,o) \ |
55 | ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o))) | 55 | ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o))) |
56 | 56 | ||
57 | #if XFS_BIG_INUMS | ||
58 | #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL)) | 57 | #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL)) |
59 | #else | ||
60 | #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 32) - 1ULL)) | ||
61 | #endif | ||
62 | #define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL)) | 58 | #define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL)) |
63 | 59 | ||
64 | #endif /* __XFS_INUM_H__ */ | 60 | #endif /* __XFS_INUM_H__ */ |
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index f0969c77bdbe..aff12f2d4428 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h | |||
@@ -380,7 +380,7 @@ typedef struct xfs_icdinode { | |||
380 | xfs_ictimestamp_t di_mtime; /* time last modified */ | 380 | xfs_ictimestamp_t di_mtime; /* time last modified */ |
381 | xfs_ictimestamp_t di_ctime; /* time created/inode modified */ | 381 | xfs_ictimestamp_t di_ctime; /* time created/inode modified */ |
382 | xfs_fsize_t di_size; /* number of bytes in file */ | 382 | xfs_fsize_t di_size; /* number of bytes in file */ |
383 | xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ | 383 | xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ |
384 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ | 384 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ |
385 | xfs_extnum_t di_nextents; /* number of extents in data fork */ | 385 | xfs_extnum_t di_nextents; /* number of extents in data fork */ |
386 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ | 386 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ |
@@ -516,7 +516,7 @@ xfs_blft_from_flags(struct xfs_buf_log_format *blf) | |||
516 | * EFI/EFD log format definitions | 516 | * EFI/EFD log format definitions |
517 | */ | 517 | */ |
518 | typedef struct xfs_extent { | 518 | typedef struct xfs_extent { |
519 | xfs_dfsbno_t ext_start; | 519 | xfs_fsblock_t ext_start; |
520 | xfs_extlen_t ext_len; | 520 | xfs_extlen_t ext_len; |
521 | } xfs_extent_t; | 521 | } xfs_extent_t; |
522 | 522 | ||
diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index 137e20937077..1b0a08379759 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h | |||
@@ -98,8 +98,6 @@ typedef __uint16_t xfs_qwarncnt_t; | |||
98 | #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ | 98 | #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ |
99 | XFS_GQUOTA_ACTIVE | \ | 99 | XFS_GQUOTA_ACTIVE | \ |
100 | XFS_PQUOTA_ACTIVE)) | 100 | XFS_PQUOTA_ACTIVE)) |
101 | #define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ | ||
102 | XFS_PQUOTA_ACTIVE)) | ||
103 | #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) | 101 | #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) |
104 | #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) | 102 | #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) |
105 | #define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) | 103 | #define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) |
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index f5ca0286a0af..6e93b5ef0a6b 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c | |||
@@ -483,10 +483,16 @@ xfs_sb_quota_to_disk( | |||
483 | } | 483 | } |
484 | 484 | ||
485 | /* | 485 | /* |
486 | * GQUOTINO and PQUOTINO cannot be used together in versions | 486 | * GQUOTINO and PQUOTINO cannot be used together in versions of |
487 | * of superblock that do not have pquotino. from->sb_flags | 487 | * superblock that do not have pquotino. from->sb_flags tells us which |
488 | * tells us which quota is active and should be copied to | 488 | * quota is active and should be copied to disk. If neither are active, |
489 | * disk. | 489 | * make sure we write NULLFSINO to the sb_gquotino field as a quota |
490 | * inode value of "0" is invalid when the XFS_SB_VERSION_QUOTA feature | ||
491 | * bit is set. | ||
492 | * | ||
493 | * Note that we don't need to handle the sb_uquotino or sb_pquotino here | ||
494 | * as they do not require any translation. Hence the main sb field loop | ||
495 | * will write them appropriately from the in-core superblock. | ||
490 | */ | 496 | */ |
491 | if ((*fields & XFS_SB_GQUOTINO) && | 497 | if ((*fields & XFS_SB_GQUOTINO) && |
492 | (from->sb_qflags & XFS_GQUOTA_ACCT)) | 498 | (from->sb_qflags & XFS_GQUOTA_ACCT)) |
@@ -494,6 +500,17 @@ xfs_sb_quota_to_disk( | |||
494 | else if ((*fields & XFS_SB_PQUOTINO) && | 500 | else if ((*fields & XFS_SB_PQUOTINO) && |
495 | (from->sb_qflags & XFS_PQUOTA_ACCT)) | 501 | (from->sb_qflags & XFS_PQUOTA_ACCT)) |
496 | to->sb_gquotino = cpu_to_be64(from->sb_pquotino); | 502 | to->sb_gquotino = cpu_to_be64(from->sb_pquotino); |
503 | else { | ||
504 | /* | ||
505 | * We can't rely on just the fields being logged to tell us | ||
506 | * that it is safe to write NULLFSINO - we should only do that | ||
507 | * if quotas are not actually enabled. Hence only write | ||
508 | * NULLFSINO if both in-core quota inodes are NULL. | ||
509 | */ | ||
510 | if (from->sb_gquotino == NULLFSINO && | ||
511 | from->sb_pquotino == NULLFSINO) | ||
512 | to->sb_gquotino = cpu_to_be64(NULLFSINO); | ||
513 | } | ||
497 | 514 | ||
498 | *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); | 515 | *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); |
499 | } | 516 | } |
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index c43c2d609a24..2e739708afd3 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h | |||
@@ -87,11 +87,11 @@ struct xfs_trans; | |||
87 | typedef struct xfs_sb { | 87 | typedef struct xfs_sb { |
88 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ | 88 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
89 | __uint32_t sb_blocksize; /* logical block size, bytes */ | 89 | __uint32_t sb_blocksize; /* logical block size, bytes */ |
90 | xfs_drfsbno_t sb_dblocks; /* number of data blocks */ | 90 | xfs_rfsblock_t sb_dblocks; /* number of data blocks */ |
91 | xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */ | 91 | xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */ |
92 | xfs_drtbno_t sb_rextents; /* number of realtime extents */ | 92 | xfs_rtblock_t sb_rextents; /* number of realtime extents */ |
93 | uuid_t sb_uuid; /* file system unique id */ | 93 | uuid_t sb_uuid; /* file system unique id */ |
94 | xfs_dfsbno_t sb_logstart; /* starting block of log if internal */ | 94 | xfs_fsblock_t sb_logstart; /* starting block of log if internal */ |
95 | xfs_ino_t sb_rootino; /* root inode number */ | 95 | xfs_ino_t sb_rootino; /* root inode number */ |
96 | xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ | 96 | xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ |
97 | xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */ | 97 | xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */ |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 56f050efcac8..d32889af1777 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -249,59 +249,6 @@ xfs_bmap_rtalloc( | |||
249 | } | 249 | } |
250 | 250 | ||
251 | /* | 251 | /* |
252 | * Stack switching interfaces for allocation | ||
253 | */ | ||
254 | static void | ||
255 | xfs_bmapi_allocate_worker( | ||
256 | struct work_struct *work) | ||
257 | { | ||
258 | struct xfs_bmalloca *args = container_of(work, | ||
259 | struct xfs_bmalloca, work); | ||
260 | unsigned long pflags; | ||
261 | unsigned long new_pflags = PF_FSTRANS; | ||
262 | |||
263 | /* | ||
264 | * we are in a transaction context here, but may also be doing work | ||
265 | * in kswapd context, and hence we may need to inherit that state | ||
266 | * temporarily to ensure that we don't block waiting for memory reclaim | ||
267 | * in any way. | ||
268 | */ | ||
269 | if (args->kswapd) | ||
270 | new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; | ||
271 | |||
272 | current_set_flags_nested(&pflags, new_pflags); | ||
273 | |||
274 | args->result = __xfs_bmapi_allocate(args); | ||
275 | complete(args->done); | ||
276 | |||
277 | current_restore_flags_nested(&pflags, new_pflags); | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * Some allocation requests often come in with little stack to work on. Push | ||
282 | * them off to a worker thread so there is lots of stack to use. Otherwise just | ||
283 | * call directly to avoid the context switch overhead here. | ||
284 | */ | ||
285 | int | ||
286 | xfs_bmapi_allocate( | ||
287 | struct xfs_bmalloca *args) | ||
288 | { | ||
289 | DECLARE_COMPLETION_ONSTACK(done); | ||
290 | |||
291 | if (!args->stack_switch) | ||
292 | return __xfs_bmapi_allocate(args); | ||
293 | |||
294 | |||
295 | args->done = &done; | ||
296 | args->kswapd = current_is_kswapd(); | ||
297 | INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); | ||
298 | queue_work(xfs_alloc_wq, &args->work); | ||
299 | wait_for_completion(&done); | ||
300 | destroy_work_on_stack(&args->work); | ||
301 | return args->result; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Check if the endoff is outside the last extent. If so the caller will grow | 252 | * Check if the endoff is outside the last extent. If so the caller will grow |
306 | * the allocation to a stripe unit boundary. All offsets are considered outside | 253 | * the allocation to a stripe unit boundary. All offsets are considered outside |
307 | * the end of file for an empty fork, so 1 is returned in *eof in that case. | 254 | * the end of file for an empty fork, so 1 is returned in *eof in that case. |
@@ -478,7 +425,7 @@ xfs_bmap_count_blocks( | |||
478 | ASSERT(level > 0); | 425 | ASSERT(level > 0); |
479 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); | 426 | pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); |
480 | bno = be64_to_cpu(*pp); | 427 | bno = be64_to_cpu(*pp); |
481 | ASSERT(bno != NULLDFSBNO); | 428 | ASSERT(bno != NULLFSBLOCK); |
482 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); | 429 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
483 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); | 430 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); |
484 | 431 | ||
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 075f72232a64..2fdb72d2c908 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h | |||
@@ -55,8 +55,6 @@ struct xfs_bmalloca { | |||
55 | bool userdata;/* set if is user data */ | 55 | bool userdata;/* set if is user data */ |
56 | bool aeof; /* allocated space at eof */ | 56 | bool aeof; /* allocated space at eof */ |
57 | bool conv; /* overwriting unwritten extents */ | 57 | bool conv; /* overwriting unwritten extents */ |
58 | bool stack_switch; | ||
59 | bool kswapd; /* allocation in kswapd context */ | ||
60 | int flags; | 58 | int flags; |
61 | struct completion *done; | 59 | struct completion *done; |
62 | struct work_struct work; | 60 | struct work_struct work; |
@@ -66,8 +64,6 @@ struct xfs_bmalloca { | |||
66 | int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, | 64 | int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, |
67 | int *committed); | 65 | int *committed); |
68 | int xfs_bmap_rtalloc(struct xfs_bmalloca *ap); | 66 | int xfs_bmap_rtalloc(struct xfs_bmalloca *ap); |
69 | int xfs_bmapi_allocate(struct xfs_bmalloca *args); | ||
70 | int __xfs_bmapi_allocate(struct xfs_bmalloca *args); | ||
71 | int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff, | 67 | int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff, |
72 | int whichfork, int *eof); | 68 | int whichfork, int *eof); |
73 | int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip, | 69 | int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip, |
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index 68a68f704837..c24c67e22a2a 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h | |||
@@ -139,6 +139,21 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type) | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | /* | ||
143 | * Check whether a dquot is under low free space conditions. We assume the quota | ||
144 | * is enabled and enforced. | ||
145 | */ | ||
146 | static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp) | ||
147 | { | ||
148 | int64_t freesp; | ||
149 | |||
150 | freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_res_bcount; | ||
151 | if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT]) | ||
152 | return true; | ||
153 | |||
154 | return false; | ||
155 | } | ||
156 | |||
142 | #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) | 157 | #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) |
143 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 158 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
144 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) | 159 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 181605da08e4..fcf91a22f5d8 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "xfs_trace.h" | 38 | #include "xfs_trace.h" |
39 | #include "xfs_log.h" | 39 | #include "xfs_log.h" |
40 | #include "xfs_dinode.h" | 40 | #include "xfs_dinode.h" |
41 | #include "xfs_icache.h" | ||
41 | 42 | ||
42 | #include <linux/aio.h> | 43 | #include <linux/aio.h> |
43 | #include <linux/dcache.h> | 44 | #include <linux/dcache.h> |
@@ -689,14 +690,28 @@ write_retry: | |||
689 | ret = generic_perform_write(file, from, pos); | 690 | ret = generic_perform_write(file, from, pos); |
690 | if (likely(ret >= 0)) | 691 | if (likely(ret >= 0)) |
691 | iocb->ki_pos = pos + ret; | 692 | iocb->ki_pos = pos + ret; |
693 | |||
692 | /* | 694 | /* |
693 | * If we just got an ENOSPC, try to write back all dirty inodes to | 695 | * If we hit a space limit, try to free up some lingering preallocated |
694 | * convert delalloc space to free up some of the excess reserved | 696 | * space before returning an error. In the case of ENOSPC, first try to |
695 | * metadata space. | 697 | * write back all dirty inodes to free up some of the excess reserved |
698 | * metadata space. This reduces the chances that the eofblocks scan | ||
699 | * waits on dirty mappings. Since xfs_flush_inodes() is serialized, this | ||
700 | * also behaves as a filter to prevent too many eofblocks scans from | ||
701 | * running at the same time. | ||
696 | */ | 702 | */ |
697 | if (ret == -ENOSPC && !enospc) { | 703 | if (ret == -EDQUOT && !enospc) { |
704 | enospc = xfs_inode_free_quota_eofblocks(ip); | ||
705 | if (enospc) | ||
706 | goto write_retry; | ||
707 | } else if (ret == -ENOSPC && !enospc) { | ||
708 | struct xfs_eofblocks eofb = {0}; | ||
709 | |||
698 | enospc = 1; | 710 | enospc = 1; |
699 | xfs_flush_inodes(ip->i_mount); | 711 | xfs_flush_inodes(ip->i_mount); |
712 | eofb.eof_scan_owner = ip->i_ino; /* for locking */ | ||
713 | eofb.eof_flags = XFS_EOF_FLAGS_SYNC; | ||
714 | xfs_icache_free_eofblocks(ip->i_mount, &eofb); | ||
700 | goto write_retry; | 715 | goto write_retry; |
701 | } | 716 | } |
702 | 717 | ||
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index d34703dbcb42..18dc721ca19f 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -255,8 +255,8 @@ typedef struct xfs_fsop_resblks { | |||
255 | ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES) | 255 | ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES) |
256 | 256 | ||
257 | /* Used for sanity checks on superblock */ | 257 | /* Used for sanity checks on superblock */ |
258 | #define XFS_MAX_DBLOCKS(s) ((xfs_drfsbno_t)(s)->sb_agcount * (s)->sb_agblocks) | 258 | #define XFS_MAX_DBLOCKS(s) ((xfs_rfsblock_t)(s)->sb_agcount * (s)->sb_agblocks) |
259 | #define XFS_MIN_DBLOCKS(s) ((xfs_drfsbno_t)((s)->sb_agcount - 1) * \ | 259 | #define XFS_MIN_DBLOCKS(s) ((xfs_rfsblock_t)((s)->sb_agcount - 1) * \ |
260 | (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) | 260 | (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) |
261 | 261 | ||
262 | /* | 262 | /* |
@@ -375,6 +375,9 @@ struct xfs_fs_eofblocks { | |||
375 | #define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */ | 375 | #define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */ |
376 | #define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */ | 376 | #define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */ |
377 | #define XFS_EOF_FLAGS_MINFILESIZE (1 << 4) /* filter by min file size */ | 377 | #define XFS_EOF_FLAGS_MINFILESIZE (1 << 4) /* filter by min file size */ |
378 | #define XFS_EOF_FLAGS_UNION (1 << 5) /* union filter algorithm; | ||
379 | * kernel only, not included in | ||
380 | * valid mask */ | ||
378 | #define XFS_EOF_FLAGS_VALID \ | 381 | #define XFS_EOF_FLAGS_VALID \ |
379 | (XFS_EOF_FLAGS_SYNC | \ | 382 | (XFS_EOF_FLAGS_SYNC | \ |
380 | XFS_EOF_FLAGS_UID | \ | 383 | XFS_EOF_FLAGS_UID | \ |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 08ba4c6e1359..981b2cf51985 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include "xfs_trace.h" | 33 | #include "xfs_trace.h" |
34 | #include "xfs_icache.h" | 34 | #include "xfs_icache.h" |
35 | #include "xfs_bmap_util.h" | 35 | #include "xfs_bmap_util.h" |
36 | #include "xfs_quota.h" | ||
37 | #include "xfs_dquot_item.h" | ||
38 | #include "xfs_dquot.h" | ||
36 | 39 | ||
37 | #include <linux/kthread.h> | 40 | #include <linux/kthread.h> |
38 | #include <linux/freezer.h> | 41 | #include <linux/freezer.h> |
@@ -1203,6 +1206,30 @@ xfs_inode_match_id( | |||
1203 | return 1; | 1206 | return 1; |
1204 | } | 1207 | } |
1205 | 1208 | ||
1209 | /* | ||
1210 | * A union-based inode filtering algorithm. Process the inode if any of the | ||
1211 | * criteria match. This is for global/internal scans only. | ||
1212 | */ | ||
1213 | STATIC int | ||
1214 | xfs_inode_match_id_union( | ||
1215 | struct xfs_inode *ip, | ||
1216 | struct xfs_eofblocks *eofb) | ||
1217 | { | ||
1218 | if ((eofb->eof_flags & XFS_EOF_FLAGS_UID) && | ||
1219 | uid_eq(VFS_I(ip)->i_uid, eofb->eof_uid)) | ||
1220 | return 1; | ||
1221 | |||
1222 | if ((eofb->eof_flags & XFS_EOF_FLAGS_GID) && | ||
1223 | gid_eq(VFS_I(ip)->i_gid, eofb->eof_gid)) | ||
1224 | return 1; | ||
1225 | |||
1226 | if ((eofb->eof_flags & XFS_EOF_FLAGS_PRID) && | ||
1227 | xfs_get_projid(ip) == eofb->eof_prid) | ||
1228 | return 1; | ||
1229 | |||
1230 | return 0; | ||
1231 | } | ||
1232 | |||
1206 | STATIC int | 1233 | STATIC int |
1207 | xfs_inode_free_eofblocks( | 1234 | xfs_inode_free_eofblocks( |
1208 | struct xfs_inode *ip, | 1235 | struct xfs_inode *ip, |
@@ -1211,6 +1238,10 @@ xfs_inode_free_eofblocks( | |||
1211 | { | 1238 | { |
1212 | int ret; | 1239 | int ret; |
1213 | struct xfs_eofblocks *eofb = args; | 1240 | struct xfs_eofblocks *eofb = args; |
1241 | bool need_iolock = true; | ||
1242 | int match; | ||
1243 | |||
1244 | ASSERT(!eofb || (eofb && eofb->eof_scan_owner != 0)); | ||
1214 | 1245 | ||
1215 | if (!xfs_can_free_eofblocks(ip, false)) { | 1246 | if (!xfs_can_free_eofblocks(ip, false)) { |
1216 | /* inode could be preallocated or append-only */ | 1247 | /* inode could be preallocated or append-only */ |
@@ -1228,16 +1259,28 @@ xfs_inode_free_eofblocks( | |||
1228 | return 0; | 1259 | return 0; |
1229 | 1260 | ||
1230 | if (eofb) { | 1261 | if (eofb) { |
1231 | if (!xfs_inode_match_id(ip, eofb)) | 1262 | if (eofb->eof_flags & XFS_EOF_FLAGS_UNION) |
1263 | match = xfs_inode_match_id_union(ip, eofb); | ||
1264 | else | ||
1265 | match = xfs_inode_match_id(ip, eofb); | ||
1266 | if (!match) | ||
1232 | return 0; | 1267 | return 0; |
1233 | 1268 | ||
1234 | /* skip the inode if the file size is too small */ | 1269 | /* skip the inode if the file size is too small */ |
1235 | if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE && | 1270 | if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE && |
1236 | XFS_ISIZE(ip) < eofb->eof_min_file_size) | 1271 | XFS_ISIZE(ip) < eofb->eof_min_file_size) |
1237 | return 0; | 1272 | return 0; |
1273 | |||
1274 | /* | ||
1275 | * A scan owner implies we already hold the iolock. Skip it in | ||
1276 | * xfs_free_eofblocks() to avoid deadlock. This also eliminates | ||
1277 | * the possibility of EAGAIN being returned. | ||
1278 | */ | ||
1279 | if (eofb->eof_scan_owner == ip->i_ino) | ||
1280 | need_iolock = false; | ||
1238 | } | 1281 | } |
1239 | 1282 | ||
1240 | ret = xfs_free_eofblocks(ip->i_mount, ip, true); | 1283 | ret = xfs_free_eofblocks(ip->i_mount, ip, need_iolock); |
1241 | 1284 | ||
1242 | /* don't revisit the inode if we're not waiting */ | 1285 | /* don't revisit the inode if we're not waiting */ |
1243 | if (ret == -EAGAIN && !(flags & SYNC_WAIT)) | 1286 | if (ret == -EAGAIN && !(flags & SYNC_WAIT)) |
@@ -1260,6 +1303,55 @@ xfs_icache_free_eofblocks( | |||
1260 | eofb, XFS_ICI_EOFBLOCKS_TAG); | 1303 | eofb, XFS_ICI_EOFBLOCKS_TAG); |
1261 | } | 1304 | } |
1262 | 1305 | ||
1306 | /* | ||
1307 | * Run eofblocks scans on the quotas applicable to the inode. For inodes with | ||
1308 | * multiple quotas, we don't know exactly which quota caused an allocation | ||
1309 | * failure. We make a best effort by including each quota under low free space | ||
1310 | * conditions (less than 1% free space) in the scan. | ||
1311 | */ | ||
1312 | int | ||
1313 | xfs_inode_free_quota_eofblocks( | ||
1314 | struct xfs_inode *ip) | ||
1315 | { | ||
1316 | int scan = 0; | ||
1317 | struct xfs_eofblocks eofb = {0}; | ||
1318 | struct xfs_dquot *dq; | ||
1319 | |||
1320 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | ||
1321 | |||
1322 | /* | ||
1323 | * Set the scan owner to avoid a potential livelock. Otherwise, the scan | ||
1324 | * can repeatedly trylock on the inode we're currently processing. We | ||
1325 | * run a sync scan to increase effectiveness and use the union filter to | ||
1326 | * cover all applicable quotas in a single scan. | ||
1327 | */ | ||
1328 | eofb.eof_scan_owner = ip->i_ino; | ||
1329 | eofb.eof_flags = XFS_EOF_FLAGS_UNION|XFS_EOF_FLAGS_SYNC; | ||
1330 | |||
1331 | if (XFS_IS_UQUOTA_ENFORCED(ip->i_mount)) { | ||
1332 | dq = xfs_inode_dquot(ip, XFS_DQ_USER); | ||
1333 | if (dq && xfs_dquot_lowsp(dq)) { | ||
1334 | eofb.eof_uid = VFS_I(ip)->i_uid; | ||
1335 | eofb.eof_flags |= XFS_EOF_FLAGS_UID; | ||
1336 | scan = 1; | ||
1337 | } | ||
1338 | } | ||
1339 | |||
1340 | if (XFS_IS_GQUOTA_ENFORCED(ip->i_mount)) { | ||
1341 | dq = xfs_inode_dquot(ip, XFS_DQ_GROUP); | ||
1342 | if (dq && xfs_dquot_lowsp(dq)) { | ||
1343 | eofb.eof_gid = VFS_I(ip)->i_gid; | ||
1344 | eofb.eof_flags |= XFS_EOF_FLAGS_GID; | ||
1345 | scan = 1; | ||
1346 | } | ||
1347 | } | ||
1348 | |||
1349 | if (scan) | ||
1350 | xfs_icache_free_eofblocks(ip->i_mount, &eofb); | ||
1351 | |||
1352 | return scan; | ||
1353 | } | ||
1354 | |||
1263 | void | 1355 | void |
1264 | xfs_inode_set_eofblocks_tag( | 1356 | xfs_inode_set_eofblocks_tag( |
1265 | xfs_inode_t *ip) | 1357 | xfs_inode_t *ip) |
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 6250430d609c..46748b86b12f 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h | |||
@@ -27,6 +27,7 @@ struct xfs_eofblocks { | |||
27 | kgid_t eof_gid; | 27 | kgid_t eof_gid; |
28 | prid_t eof_prid; | 28 | prid_t eof_prid; |
29 | __u64 eof_min_file_size; | 29 | __u64 eof_min_file_size; |
30 | xfs_ino_t eof_scan_owner; | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | #define SYNC_WAIT 0x0001 /* wait for i/o to complete */ | 33 | #define SYNC_WAIT 0x0001 /* wait for i/o to complete */ |
@@ -57,6 +58,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); | |||
57 | void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); | 58 | void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); |
58 | void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); | 59 | void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); |
59 | int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *); | 60 | int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *); |
61 | int xfs_inode_free_quota_eofblocks(struct xfs_inode *ip); | ||
60 | void xfs_eofblocks_worker(struct work_struct *); | 62 | void xfs_eofblocks_worker(struct work_struct *); |
61 | 63 | ||
62 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 64 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
@@ -84,6 +86,7 @@ xfs_fs_eofblocks_from_user( | |||
84 | dst->eof_flags = src->eof_flags; | 86 | dst->eof_flags = src->eof_flags; |
85 | dst->eof_prid = src->eof_prid; | 87 | dst->eof_prid = src->eof_prid; |
86 | dst->eof_min_file_size = src->eof_min_file_size; | 88 | dst->eof_min_file_size = src->eof_min_file_size; |
89 | dst->eof_scan_owner = NULLFSINO; | ||
87 | 90 | ||
88 | dst->eof_uid = INVALID_UID; | 91 | dst->eof_uid = INVALID_UID; |
89 | if (src->eof_flags & XFS_EOF_FLAGS_UID) { | 92 | if (src->eof_flags & XFS_EOF_FLAGS_UID) { |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 923c044bd26f..e9c47b6f5e5a 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -397,7 +397,8 @@ xfs_quota_calc_throttle( | |||
397 | struct xfs_inode *ip, | 397 | struct xfs_inode *ip, |
398 | int type, | 398 | int type, |
399 | xfs_fsblock_t *qblocks, | 399 | xfs_fsblock_t *qblocks, |
400 | int *qshift) | 400 | int *qshift, |
401 | int64_t *qfreesp) | ||
401 | { | 402 | { |
402 | int64_t freesp; | 403 | int64_t freesp; |
403 | int shift = 0; | 404 | int shift = 0; |
@@ -406,6 +407,7 @@ xfs_quota_calc_throttle( | |||
406 | /* over hi wmark, squash the prealloc completely */ | 407 | /* over hi wmark, squash the prealloc completely */ |
407 | if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) { | 408 | if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) { |
408 | *qblocks = 0; | 409 | *qblocks = 0; |
410 | *qfreesp = 0; | ||
409 | return; | 411 | return; |
410 | } | 412 | } |
411 | 413 | ||
@@ -418,6 +420,9 @@ xfs_quota_calc_throttle( | |||
418 | shift += 2; | 420 | shift += 2; |
419 | } | 421 | } |
420 | 422 | ||
423 | if (freesp < *qfreesp) | ||
424 | *qfreesp = freesp; | ||
425 | |||
421 | /* only overwrite the throttle values if we are more aggressive */ | 426 | /* only overwrite the throttle values if we are more aggressive */ |
422 | if ((freesp >> shift) < (*qblocks >> *qshift)) { | 427 | if ((freesp >> shift) < (*qblocks >> *qshift)) { |
423 | *qblocks = freesp; | 428 | *qblocks = freesp; |
@@ -476,15 +481,18 @@ xfs_iomap_prealloc_size( | |||
476 | } | 481 | } |
477 | 482 | ||
478 | /* | 483 | /* |
479 | * Check each quota to cap the prealloc size and provide a shift | 484 | * Check each quota to cap the prealloc size, provide a shift value to |
480 | * value to throttle with. | 485 | * throttle with and adjust amount of available space. |
481 | */ | 486 | */ |
482 | if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks)) | 487 | if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks)) |
483 | xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift); | 488 | xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift, |
489 | &freesp); | ||
484 | if (xfs_quota_need_throttle(ip, XFS_DQ_GROUP, alloc_blocks)) | 490 | if (xfs_quota_need_throttle(ip, XFS_DQ_GROUP, alloc_blocks)) |
485 | xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift); | 491 | xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift, |
492 | &freesp); | ||
486 | if (xfs_quota_need_throttle(ip, XFS_DQ_PROJ, alloc_blocks)) | 493 | if (xfs_quota_need_throttle(ip, XFS_DQ_PROJ, alloc_blocks)) |
487 | xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift); | 494 | xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift, |
495 | &freesp); | ||
488 | 496 | ||
489 | /* | 497 | /* |
490 | * The final prealloc size is set to the minimum of free space available | 498 | * The final prealloc size is set to the minimum of free space available |
@@ -749,8 +757,7 @@ xfs_iomap_write_allocate( | |||
749 | * pointer that the caller gave to us. | 757 | * pointer that the caller gave to us. |
750 | */ | 758 | */ |
751 | error = xfs_bmapi_write(tp, ip, map_start_fsb, | 759 | error = xfs_bmapi_write(tp, ip, map_start_fsb, |
752 | count_fsb, | 760 | count_fsb, 0, |
753 | XFS_BMAPI_STACK_SWITCH, | ||
754 | &first_block, 1, | 761 | &first_block, 1, |
755 | imap, &nimaps, &free_list); | 762 | imap, &nimaps, &free_list); |
756 | if (error) | 763 | if (error) |
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index f59b966bf903..d3ef6de475bb 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h | |||
@@ -21,18 +21,6 @@ | |||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits. | ||
25 | * XFS_BIG_INUMS requires XFS_BIG_BLKNOS to be set. | ||
26 | */ | ||
27 | #if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) | ||
28 | # define XFS_BIG_BLKNOS 1 | ||
29 | # define XFS_BIG_INUMS 1 | ||
30 | #else | ||
31 | # define XFS_BIG_BLKNOS 0 | ||
32 | # define XFS_BIG_INUMS 0 | ||
33 | #endif | ||
34 | |||
35 | /* | ||
36 | * Kernel specific type declarations for XFS | 24 | * Kernel specific type declarations for XFS |
37 | */ | 25 | */ |
38 | typedef signed char __int8_t; | 26 | typedef signed char __int8_t; |
@@ -191,6 +179,17 @@ typedef __uint64_t __psunsigned_t; | |||
191 | #define MAX(a,b) (max(a,b)) | 179 | #define MAX(a,b) (max(a,b)) |
192 | #define howmany(x, y) (((x)+((y)-1))/(y)) | 180 | #define howmany(x, y) (((x)+((y)-1))/(y)) |
193 | 181 | ||
182 | /* | ||
183 | * XFS wrapper structure for sysfs support. It depends on external data | ||
184 | * structures and is embedded in various internal data structures to implement | ||
185 | * the XFS sysfs object heirarchy. Define it here for broad access throughout | ||
186 | * the codebase. | ||
187 | */ | ||
188 | struct xfs_kobj { | ||
189 | struct kobject kobject; | ||
190 | struct completion complete; | ||
191 | }; | ||
192 | |||
194 | /* Kernel uid/gid conversion. These are used to convert to/from the on disk | 193 | /* Kernel uid/gid conversion. These are used to convert to/from the on disk |
195 | * uid_t/gid_t types to the kuid_t/kgid_t types that the kernel uses internally. | 194 | * uid_t/gid_t types to the kuid_t/kgid_t types that the kernel uses internally. |
196 | * The conversion here is type only, the value will remain the same since we | 195 | * The conversion here is type only, the value will remain the same since we |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 7647818b8c8a..149a4a575a09 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "xfs_trace.h" | 34 | #include "xfs_trace.h" |
35 | #include "xfs_fsops.h" | 35 | #include "xfs_fsops.h" |
36 | #include "xfs_cksum.h" | 36 | #include "xfs_cksum.h" |
37 | #include "xfs_sysfs.h" | ||
37 | 38 | ||
38 | kmem_zone_t *xfs_log_ticket_zone; | 39 | kmem_zone_t *xfs_log_ticket_zone; |
39 | 40 | ||
@@ -707,6 +708,11 @@ xfs_log_mount( | |||
707 | } | 708 | } |
708 | } | 709 | } |
709 | 710 | ||
711 | error = xfs_sysfs_init(&mp->m_log->l_kobj, &xfs_log_ktype, &mp->m_kobj, | ||
712 | "log"); | ||
713 | if (error) | ||
714 | goto out_destroy_ail; | ||
715 | |||
710 | /* Normal transactions can now occur */ | 716 | /* Normal transactions can now occur */ |
711 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; | 717 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; |
712 | 718 | ||
@@ -947,6 +953,9 @@ xfs_log_unmount( | |||
947 | xfs_log_quiesce(mp); | 953 | xfs_log_quiesce(mp); |
948 | 954 | ||
949 | xfs_trans_ail_destroy(mp); | 955 | xfs_trans_ail_destroy(mp); |
956 | |||
957 | xfs_sysfs_del(&mp->m_log->l_kobj); | ||
958 | |||
950 | xlog_dealloc_log(mp->m_log); | 959 | xlog_dealloc_log(mp->m_log); |
951 | } | 960 | } |
952 | 961 | ||
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 2ee4388dc682..f6b79e5325dd 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -78,8 +78,6 @@ xlog_cil_init_post_recovery( | |||
78 | { | 78 | { |
79 | log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); | 79 | log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); |
80 | log->l_cilp->xc_ctx->sequence = 1; | 80 | log->l_cilp->xc_ctx->sequence = 1; |
81 | log->l_cilp->xc_ctx->commit_lsn = xlog_assign_lsn(log->l_curr_cycle, | ||
82 | log->l_curr_block); | ||
83 | } | 81 | } |
84 | 82 | ||
85 | /* | 83 | /* |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 9bc403a9e54f..db7cbdeb2b42 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -405,6 +405,8 @@ struct xlog { | |||
405 | struct xlog_grant_head l_reserve_head; | 405 | struct xlog_grant_head l_reserve_head; |
406 | struct xlog_grant_head l_write_head; | 406 | struct xlog_grant_head l_write_head; |
407 | 407 | ||
408 | struct xfs_kobj l_kobj; | ||
409 | |||
408 | /* The following field are used for debugging; need to hold icloglock */ | 410 | /* The following field are used for debugging; need to hold icloglock */ |
409 | #ifdef DEBUG | 411 | #ifdef DEBUG |
410 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; | 412 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d5c44a6bdb5b..5b639df0413e 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "xfs_trace.h" | 42 | #include "xfs_trace.h" |
43 | #include "xfs_icache.h" | 43 | #include "xfs_icache.h" |
44 | #include "xfs_dinode.h" | 44 | #include "xfs_dinode.h" |
45 | #include "xfs_sysfs.h" | ||
45 | 46 | ||
46 | 47 | ||
47 | #ifdef HAVE_PERCPU_SB | 48 | #ifdef HAVE_PERCPU_SB |
@@ -60,6 +61,8 @@ static DEFINE_MUTEX(xfs_uuid_table_mutex); | |||
60 | static int xfs_uuid_table_size; | 61 | static int xfs_uuid_table_size; |
61 | static uuid_t *xfs_uuid_table; | 62 | static uuid_t *xfs_uuid_table; |
62 | 63 | ||
64 | extern struct kset *xfs_kset; | ||
65 | |||
63 | /* | 66 | /* |
64 | * See if the UUID is unique among mounted XFS filesystems. | 67 | * See if the UUID is unique among mounted XFS filesystems. |
65 | * Mount fails if UUID is nil or a FS with the same UUID is already mounted. | 68 | * Mount fails if UUID is nil or a FS with the same UUID is already mounted. |
@@ -173,13 +176,9 @@ xfs_sb_validate_fsb_count( | |||
173 | ASSERT(PAGE_SHIFT >= sbp->sb_blocklog); | 176 | ASSERT(PAGE_SHIFT >= sbp->sb_blocklog); |
174 | ASSERT(sbp->sb_blocklog >= BBSHIFT); | 177 | ASSERT(sbp->sb_blocklog >= BBSHIFT); |
175 | 178 | ||
176 | #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ | 179 | /* Limited by ULONG_MAX of page cache index */ |
177 | if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) | 180 | if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) |
178 | return -EFBIG; | 181 | return -EFBIG; |
179 | #else /* Limited by UINT_MAX of sectors */ | ||
180 | if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) | ||
181 | return -EFBIG; | ||
182 | #endif | ||
183 | return 0; | 182 | return 0; |
184 | } | 183 | } |
185 | 184 | ||
@@ -250,9 +249,9 @@ xfs_initialize_perag( | |||
250 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | 249 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; |
251 | 250 | ||
252 | if (mp->m_flags & XFS_MOUNT_32BITINODES) | 251 | if (mp->m_flags & XFS_MOUNT_32BITINODES) |
253 | index = xfs_set_inode32(mp); | 252 | index = xfs_set_inode32(mp, agcount); |
254 | else | 253 | else |
255 | index = xfs_set_inode64(mp); | 254 | index = xfs_set_inode64(mp, agcount); |
256 | 255 | ||
257 | if (maxagi) | 256 | if (maxagi) |
258 | *maxagi = index; | 257 | *maxagi = index; |
@@ -731,10 +730,15 @@ xfs_mountfs( | |||
731 | 730 | ||
732 | xfs_set_maxicount(mp); | 731 | xfs_set_maxicount(mp); |
733 | 732 | ||
734 | error = xfs_uuid_mount(mp); | 733 | mp->m_kobj.kobject.kset = xfs_kset; |
734 | error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname); | ||
735 | if (error) | 735 | if (error) |
736 | goto out; | 736 | goto out; |
737 | 737 | ||
738 | error = xfs_uuid_mount(mp); | ||
739 | if (error) | ||
740 | goto out_remove_sysfs; | ||
741 | |||
738 | /* | 742 | /* |
739 | * Set the minimum read and write sizes | 743 | * Set the minimum read and write sizes |
740 | */ | 744 | */ |
@@ -855,7 +859,7 @@ xfs_mountfs( | |||
855 | !mp->m_sb.sb_inprogress) { | 859 | !mp->m_sb.sb_inprogress) { |
856 | error = xfs_initialize_perag_data(mp, sbp->sb_agcount); | 860 | error = xfs_initialize_perag_data(mp, sbp->sb_agcount); |
857 | if (error) | 861 | if (error) |
858 | goto out_fail_wait; | 862 | goto out_log_dealloc; |
859 | } | 863 | } |
860 | 864 | ||
861 | /* | 865 | /* |
@@ -927,7 +931,7 @@ xfs_mountfs( | |||
927 | xfs_notice(mp, "resetting quota flags"); | 931 | xfs_notice(mp, "resetting quota flags"); |
928 | error = xfs_mount_reset_sbqflags(mp); | 932 | error = xfs_mount_reset_sbqflags(mp); |
929 | if (error) | 933 | if (error) |
930 | return error; | 934 | goto out_rtunmount; |
931 | } | 935 | } |
932 | } | 936 | } |
933 | 937 | ||
@@ -989,6 +993,8 @@ xfs_mountfs( | |||
989 | xfs_da_unmount(mp); | 993 | xfs_da_unmount(mp); |
990 | out_remove_uuid: | 994 | out_remove_uuid: |
991 | xfs_uuid_unmount(mp); | 995 | xfs_uuid_unmount(mp); |
996 | out_remove_sysfs: | ||
997 | xfs_sysfs_del(&mp->m_kobj); | ||
992 | out: | 998 | out: |
993 | return error; | 999 | return error; |
994 | } | 1000 | } |
@@ -1071,6 +1077,8 @@ xfs_unmountfs( | |||
1071 | xfs_errortag_clearall(mp, 0); | 1077 | xfs_errortag_clearall(mp, 0); |
1072 | #endif | 1078 | #endif |
1073 | xfs_free_perag(mp); | 1079 | xfs_free_perag(mp); |
1080 | |||
1081 | xfs_sysfs_del(&mp->m_kobj); | ||
1074 | } | 1082 | } |
1075 | 1083 | ||
1076 | int | 1084 | int |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7295a0b7c343..b0447c86e7e2 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -166,6 +166,7 @@ typedef struct xfs_mount { | |||
166 | on the next remount,rw */ | 166 | on the next remount,rw */ |
167 | int64_t m_low_space[XFS_LOWSP_MAX]; | 167 | int64_t m_low_space[XFS_LOWSP_MAX]; |
168 | /* low free space thresholds */ | 168 | /* low free space thresholds */ |
169 | struct xfs_kobj m_kobj; | ||
169 | 170 | ||
170 | struct workqueue_struct *m_data_workqueue; | 171 | struct workqueue_struct *m_data_workqueue; |
171 | struct workqueue_struct *m_unwritten_workqueue; | 172 | struct workqueue_struct *m_unwritten_workqueue; |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index ba284f6469db..7e1a80b45f87 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -221,100 +221,6 @@ xfs_qm_unmount( | |||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
224 | |||
225 | /* | ||
226 | * This is called from xfs_mountfs to start quotas and initialize all | ||
227 | * necessary data structures like quotainfo. This is also responsible for | ||
228 | * running a quotacheck as necessary. We are guaranteed that the superblock | ||
229 | * is consistently read in at this point. | ||
230 | * | ||
231 | * If we fail here, the mount will continue with quota turned off. We don't | ||
232 | * need to inidicate success or failure at all. | ||
233 | */ | ||
234 | void | ||
235 | xfs_qm_mount_quotas( | ||
236 | xfs_mount_t *mp) | ||
237 | { | ||
238 | int error = 0; | ||
239 | uint sbf; | ||
240 | |||
241 | /* | ||
242 | * If quotas on realtime volumes is not supported, we disable | ||
243 | * quotas immediately. | ||
244 | */ | ||
245 | if (mp->m_sb.sb_rextents) { | ||
246 | xfs_notice(mp, "Cannot turn on quotas for realtime filesystem"); | ||
247 | mp->m_qflags = 0; | ||
248 | goto write_changes; | ||
249 | } | ||
250 | |||
251 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | ||
252 | |||
253 | /* | ||
254 | * Allocate the quotainfo structure inside the mount struct, and | ||
255 | * create quotainode(s), and change/rev superblock if necessary. | ||
256 | */ | ||
257 | error = xfs_qm_init_quotainfo(mp); | ||
258 | if (error) { | ||
259 | /* | ||
260 | * We must turn off quotas. | ||
261 | */ | ||
262 | ASSERT(mp->m_quotainfo == NULL); | ||
263 | mp->m_qflags = 0; | ||
264 | goto write_changes; | ||
265 | } | ||
266 | /* | ||
267 | * If any of the quotas are not consistent, do a quotacheck. | ||
268 | */ | ||
269 | if (XFS_QM_NEED_QUOTACHECK(mp)) { | ||
270 | error = xfs_qm_quotacheck(mp); | ||
271 | if (error) { | ||
272 | /* Quotacheck failed and disabled quotas. */ | ||
273 | return; | ||
274 | } | ||
275 | } | ||
276 | /* | ||
277 | * If one type of quotas is off, then it will lose its | ||
278 | * quotachecked status, since we won't be doing accounting for | ||
279 | * that type anymore. | ||
280 | */ | ||
281 | if (!XFS_IS_UQUOTA_ON(mp)) | ||
282 | mp->m_qflags &= ~XFS_UQUOTA_CHKD; | ||
283 | if (!XFS_IS_GQUOTA_ON(mp)) | ||
284 | mp->m_qflags &= ~XFS_GQUOTA_CHKD; | ||
285 | if (!XFS_IS_PQUOTA_ON(mp)) | ||
286 | mp->m_qflags &= ~XFS_PQUOTA_CHKD; | ||
287 | |||
288 | write_changes: | ||
289 | /* | ||
290 | * We actually don't have to acquire the m_sb_lock at all. | ||
291 | * This can only be called from mount, and that's single threaded. XXX | ||
292 | */ | ||
293 | spin_lock(&mp->m_sb_lock); | ||
294 | sbf = mp->m_sb.sb_qflags; | ||
295 | mp->m_sb.sb_qflags = mp->m_qflags & XFS_MOUNT_QUOTA_ALL; | ||
296 | spin_unlock(&mp->m_sb_lock); | ||
297 | |||
298 | if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { | ||
299 | if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { | ||
300 | /* | ||
301 | * We could only have been turning quotas off. | ||
302 | * We aren't in very good shape actually because | ||
303 | * the incore structures are convinced that quotas are | ||
304 | * off, but the on disk superblock doesn't know that ! | ||
305 | */ | ||
306 | ASSERT(!(XFS_IS_QUOTA_RUNNING(mp))); | ||
307 | xfs_alert(mp, "%s: Superblock update failed!", | ||
308 | __func__); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | if (error) { | ||
313 | xfs_warn(mp, "Failed to initialize disk quotas."); | ||
314 | return; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /* | 224 | /* |
319 | * Called from the vfsops layer. | 225 | * Called from the vfsops layer. |
320 | */ | 226 | */ |
@@ -1330,7 +1236,7 @@ out_unlock: | |||
1330 | * Walk thru all the filesystem inodes and construct a consistent view | 1236 | * Walk thru all the filesystem inodes and construct a consistent view |
1331 | * of the disk quota world. If the quotacheck fails, disable quotas. | 1237 | * of the disk quota world. If the quotacheck fails, disable quotas. |
1332 | */ | 1238 | */ |
1333 | int | 1239 | STATIC int |
1334 | xfs_qm_quotacheck( | 1240 | xfs_qm_quotacheck( |
1335 | xfs_mount_t *mp) | 1241 | xfs_mount_t *mp) |
1336 | { | 1242 | { |
@@ -1467,6 +1373,99 @@ xfs_qm_quotacheck( | |||
1467 | } | 1373 | } |
1468 | 1374 | ||
1469 | /* | 1375 | /* |
1376 | * This is called from xfs_mountfs to start quotas and initialize all | ||
1377 | * necessary data structures like quotainfo. This is also responsible for | ||
1378 | * running a quotacheck as necessary. We are guaranteed that the superblock | ||
1379 | * is consistently read in at this point. | ||
1380 | * | ||
1381 | * If we fail here, the mount will continue with quota turned off. We don't | ||
1382 | * need to inidicate success or failure at all. | ||
1383 | */ | ||
1384 | void | ||
1385 | xfs_qm_mount_quotas( | ||
1386 | struct xfs_mount *mp) | ||
1387 | { | ||
1388 | int error = 0; | ||
1389 | uint sbf; | ||
1390 | |||
1391 | /* | ||
1392 | * If quotas on realtime volumes is not supported, we disable | ||
1393 | * quotas immediately. | ||
1394 | */ | ||
1395 | if (mp->m_sb.sb_rextents) { | ||
1396 | xfs_notice(mp, "Cannot turn on quotas for realtime filesystem"); | ||
1397 | mp->m_qflags = 0; | ||
1398 | goto write_changes; | ||
1399 | } | ||
1400 | |||
1401 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | ||
1402 | |||
1403 | /* | ||
1404 | * Allocate the quotainfo structure inside the mount struct, and | ||
1405 | * create quotainode(s), and change/rev superblock if necessary. | ||
1406 | */ | ||
1407 | error = xfs_qm_init_quotainfo(mp); | ||
1408 | if (error) { | ||
1409 | /* | ||
1410 | * We must turn off quotas. | ||
1411 | */ | ||
1412 | ASSERT(mp->m_quotainfo == NULL); | ||
1413 | mp->m_qflags = 0; | ||
1414 | goto write_changes; | ||
1415 | } | ||
1416 | /* | ||
1417 | * If any of the quotas are not consistent, do a quotacheck. | ||
1418 | */ | ||
1419 | if (XFS_QM_NEED_QUOTACHECK(mp)) { | ||
1420 | error = xfs_qm_quotacheck(mp); | ||
1421 | if (error) { | ||
1422 | /* Quotacheck failed and disabled quotas. */ | ||
1423 | return; | ||
1424 | } | ||
1425 | } | ||
1426 | /* | ||
1427 | * If one type of quotas is off, then it will lose its | ||
1428 | * quotachecked status, since we won't be doing accounting for | ||
1429 | * that type anymore. | ||
1430 | */ | ||
1431 | if (!XFS_IS_UQUOTA_ON(mp)) | ||
1432 | mp->m_qflags &= ~XFS_UQUOTA_CHKD; | ||
1433 | if (!XFS_IS_GQUOTA_ON(mp)) | ||
1434 | mp->m_qflags &= ~XFS_GQUOTA_CHKD; | ||
1435 | if (!XFS_IS_PQUOTA_ON(mp)) | ||
1436 | mp->m_qflags &= ~XFS_PQUOTA_CHKD; | ||
1437 | |||
1438 | write_changes: | ||
1439 | /* | ||
1440 | * We actually don't have to acquire the m_sb_lock at all. | ||
1441 | * This can only be called from mount, and that's single threaded. XXX | ||
1442 | */ | ||
1443 | spin_lock(&mp->m_sb_lock); | ||
1444 | sbf = mp->m_sb.sb_qflags; | ||
1445 | mp->m_sb.sb_qflags = mp->m_qflags & XFS_MOUNT_QUOTA_ALL; | ||
1446 | spin_unlock(&mp->m_sb_lock); | ||
1447 | |||
1448 | if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { | ||
1449 | if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { | ||
1450 | /* | ||
1451 | * We could only have been turning quotas off. | ||
1452 | * We aren't in very good shape actually because | ||
1453 | * the incore structures are convinced that quotas are | ||
1454 | * off, but the on disk superblock doesn't know that ! | ||
1455 | */ | ||
1456 | ASSERT(!(XFS_IS_QUOTA_RUNNING(mp))); | ||
1457 | xfs_alert(mp, "%s: Superblock update failed!", | ||
1458 | __func__); | ||
1459 | } | ||
1460 | } | ||
1461 | |||
1462 | if (error) { | ||
1463 | xfs_warn(mp, "Failed to initialize disk quotas."); | ||
1464 | return; | ||
1465 | } | ||
1466 | } | ||
1467 | |||
1468 | /* | ||
1470 | * This is called after the superblock has been read in and we're ready to | 1469 | * This is called after the superblock has been read in and we're ready to |
1471 | * iget the quota inodes. | 1470 | * iget the quota inodes. |
1472 | */ | 1471 | */ |
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 797fd4636273..3a07a937e232 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 | ||
159 | extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); | 159 | extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); |
160 | extern int xfs_qm_quotacheck(struct xfs_mount *); | ||
161 | extern int xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t); | 160 | extern int xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t); |
162 | 161 | ||
163 | /* dquot stuff */ | 162 | /* dquot stuff */ |
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 4f7aecbe61da..b238027df987 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c | |||
@@ -123,7 +123,7 @@ xfs_fs_rm_xquota( | |||
123 | flags |= XFS_DQ_USER; | 123 | flags |= XFS_DQ_USER; |
124 | if (uflags & FS_GROUP_QUOTA) | 124 | if (uflags & FS_GROUP_QUOTA) |
125 | flags |= XFS_DQ_GROUP; | 125 | flags |= XFS_DQ_GROUP; |
126 | if (uflags & FS_USER_QUOTA) | 126 | if (uflags & FS_PROJ_QUOTA) |
127 | flags |= XFS_DQ_PROJ; | 127 | flags |= XFS_DQ_PROJ; |
128 | 128 | ||
129 | return xfs_qm_scall_trunc_qfiles(mp, flags); | 129 | return xfs_qm_scall_trunc_qfiles(mp, flags); |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index b741d7286990..909e143b87ae 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -944,9 +944,9 @@ xfs_growfs_rt( | |||
944 | xfs_buf_t *bp; /* temporary buffer */ | 944 | xfs_buf_t *bp; /* temporary buffer */ |
945 | int error; /* error return value */ | 945 | int error; /* error return value */ |
946 | xfs_mount_t *nmp; /* new (fake) mount structure */ | 946 | xfs_mount_t *nmp; /* new (fake) mount structure */ |
947 | xfs_drfsbno_t nrblocks; /* new number of realtime blocks */ | 947 | xfs_rfsblock_t nrblocks; /* new number of realtime blocks */ |
948 | xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ | 948 | xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ |
949 | xfs_drtbno_t nrextents; /* new number of realtime extents */ | 949 | xfs_rtblock_t nrextents; /* new number of realtime extents */ |
950 | uint8_t nrextslog; /* new log2 of sb_rextents */ | 950 | uint8_t nrextslog; /* new log2 of sb_rextents */ |
951 | xfs_extlen_t nrsumblocks; /* new number of summary blocks */ | 951 | xfs_extlen_t nrsumblocks; /* new number of summary blocks */ |
952 | uint nrsumlevels; /* new rt summary levels */ | 952 | uint nrsumlevels; /* new rt summary levels */ |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index f2e5f8a503d2..b194652033cd 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -61,6 +61,7 @@ | |||
61 | static const struct super_operations xfs_super_operations; | 61 | static const struct super_operations xfs_super_operations; |
62 | static kmem_zone_t *xfs_ioend_zone; | 62 | static kmem_zone_t *xfs_ioend_zone; |
63 | mempool_t *xfs_ioend_pool; | 63 | mempool_t *xfs_ioend_pool; |
64 | struct kset *xfs_kset; | ||
64 | 65 | ||
65 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | 66 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ |
66 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | 67 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ |
@@ -204,9 +205,6 @@ xfs_parseargs( | |||
204 | */ | 205 | */ |
205 | mp->m_flags |= XFS_MOUNT_BARRIER; | 206 | mp->m_flags |= XFS_MOUNT_BARRIER; |
206 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 207 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
207 | #if !XFS_BIG_INUMS | ||
208 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | ||
209 | #endif | ||
210 | 208 | ||
211 | /* | 209 | /* |
212 | * These can be overridden by the mount option parsing. | 210 | * These can be overridden by the mount option parsing. |
@@ -313,11 +311,6 @@ xfs_parseargs( | |||
313 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 311 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
314 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 312 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { |
315 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; | 313 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
316 | #if !XFS_BIG_INUMS | ||
317 | xfs_warn(mp, "%s option not allowed on this system", | ||
318 | this_char); | ||
319 | return -EINVAL; | ||
320 | #endif | ||
321 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 314 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { |
322 | mp->m_flags |= XFS_MOUNT_NOUUID; | 315 | mp->m_flags |= XFS_MOUNT_NOUUID; |
323 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | 316 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { |
@@ -597,15 +590,20 @@ xfs_max_file_offset( | |||
597 | return (((__uint64_t)pagefactor) << bitshift) - 1; | 590 | return (((__uint64_t)pagefactor) << bitshift) - 1; |
598 | } | 591 | } |
599 | 592 | ||
593 | /* | ||
594 | * xfs_set_inode32() and xfs_set_inode64() are passed an agcount | ||
595 | * because in the growfs case, mp->m_sb.sb_agcount is not updated | ||
596 | * yet to the potentially higher ag count. | ||
597 | */ | ||
600 | xfs_agnumber_t | 598 | xfs_agnumber_t |
601 | xfs_set_inode32(struct xfs_mount *mp) | 599 | xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) |
602 | { | 600 | { |
603 | xfs_agnumber_t index = 0; | 601 | xfs_agnumber_t index = 0; |
604 | xfs_agnumber_t maxagi = 0; | 602 | xfs_agnumber_t maxagi = 0; |
605 | xfs_sb_t *sbp = &mp->m_sb; | 603 | xfs_sb_t *sbp = &mp->m_sb; |
606 | xfs_agnumber_t max_metadata; | 604 | xfs_agnumber_t max_metadata; |
607 | xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0); | 605 | xfs_agino_t agino; |
608 | xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino); | 606 | xfs_ino_t ino; |
609 | xfs_perag_t *pag; | 607 | xfs_perag_t *pag; |
610 | 608 | ||
611 | /* Calculate how much should be reserved for inodes to meet | 609 | /* Calculate how much should be reserved for inodes to meet |
@@ -620,10 +618,12 @@ xfs_set_inode32(struct xfs_mount *mp) | |||
620 | do_div(icount, sbp->sb_agblocks); | 618 | do_div(icount, sbp->sb_agblocks); |
621 | max_metadata = icount; | 619 | max_metadata = icount; |
622 | } else { | 620 | } else { |
623 | max_metadata = sbp->sb_agcount; | 621 | max_metadata = agcount; |
624 | } | 622 | } |
625 | 623 | ||
626 | for (index = 0; index < sbp->sb_agcount; index++) { | 624 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); |
625 | |||
626 | for (index = 0; index < agcount; index++) { | ||
627 | ino = XFS_AGINO_TO_INO(mp, index, agino); | 627 | ino = XFS_AGINO_TO_INO(mp, index, agino); |
628 | 628 | ||
629 | if (ino > XFS_MAXINUMBER_32) { | 629 | if (ino > XFS_MAXINUMBER_32) { |
@@ -648,11 +648,11 @@ xfs_set_inode32(struct xfs_mount *mp) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | xfs_agnumber_t | 650 | xfs_agnumber_t |
651 | xfs_set_inode64(struct xfs_mount *mp) | 651 | xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount) |
652 | { | 652 | { |
653 | xfs_agnumber_t index = 0; | 653 | xfs_agnumber_t index = 0; |
654 | 654 | ||
655 | for (index = 0; index < mp->m_sb.sb_agcount; index++) { | 655 | for (index = 0; index < agcount; index++) { |
656 | struct xfs_perag *pag; | 656 | struct xfs_perag *pag; |
657 | 657 | ||
658 | pag = xfs_perag_get(mp, index); | 658 | pag = xfs_perag_get(mp, index); |
@@ -1188,6 +1188,7 @@ xfs_fs_remount( | |||
1188 | char *options) | 1188 | char *options) |
1189 | { | 1189 | { |
1190 | struct xfs_mount *mp = XFS_M(sb); | 1190 | struct xfs_mount *mp = XFS_M(sb); |
1191 | xfs_sb_t *sbp = &mp->m_sb; | ||
1191 | substring_t args[MAX_OPT_ARGS]; | 1192 | substring_t args[MAX_OPT_ARGS]; |
1192 | char *p; | 1193 | char *p; |
1193 | int error; | 1194 | int error; |
@@ -1208,10 +1209,10 @@ xfs_fs_remount( | |||
1208 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1209 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
1209 | break; | 1210 | break; |
1210 | case Opt_inode64: | 1211 | case Opt_inode64: |
1211 | mp->m_maxagi = xfs_set_inode64(mp); | 1212 | mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount); |
1212 | break; | 1213 | break; |
1213 | case Opt_inode32: | 1214 | case Opt_inode32: |
1214 | mp->m_maxagi = xfs_set_inode32(mp); | 1215 | mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount); |
1215 | break; | 1216 | break; |
1216 | default: | 1217 | default: |
1217 | /* | 1218 | /* |
@@ -1761,9 +1762,15 @@ init_xfs_fs(void) | |||
1761 | if (error) | 1762 | if (error) |
1762 | goto out_cleanup_procfs; | 1763 | goto out_cleanup_procfs; |
1763 | 1764 | ||
1765 | xfs_kset = kset_create_and_add("xfs", NULL, fs_kobj); | ||
1766 | if (!xfs_kset) { | ||
1767 | error = -ENOMEM; | ||
1768 | goto out_sysctl_unregister;; | ||
1769 | } | ||
1770 | |||
1764 | error = xfs_qm_init(); | 1771 | error = xfs_qm_init(); |
1765 | if (error) | 1772 | if (error) |
1766 | goto out_sysctl_unregister; | 1773 | goto out_kset_unregister; |
1767 | 1774 | ||
1768 | error = register_filesystem(&xfs_fs_type); | 1775 | error = register_filesystem(&xfs_fs_type); |
1769 | if (error) | 1776 | if (error) |
@@ -1772,6 +1779,8 @@ init_xfs_fs(void) | |||
1772 | 1779 | ||
1773 | out_qm_exit: | 1780 | out_qm_exit: |
1774 | xfs_qm_exit(); | 1781 | xfs_qm_exit(); |
1782 | out_kset_unregister: | ||
1783 | kset_unregister(xfs_kset); | ||
1775 | out_sysctl_unregister: | 1784 | out_sysctl_unregister: |
1776 | xfs_sysctl_unregister(); | 1785 | xfs_sysctl_unregister(); |
1777 | out_cleanup_procfs: | 1786 | out_cleanup_procfs: |
@@ -1793,6 +1802,7 @@ exit_xfs_fs(void) | |||
1793 | { | 1802 | { |
1794 | xfs_qm_exit(); | 1803 | xfs_qm_exit(); |
1795 | unregister_filesystem(&xfs_fs_type); | 1804 | unregister_filesystem(&xfs_fs_type); |
1805 | kset_unregister(xfs_kset); | ||
1796 | xfs_sysctl_unregister(); | 1806 | xfs_sysctl_unregister(); |
1797 | xfs_cleanup_procfs(); | 1807 | xfs_cleanup_procfs(); |
1798 | xfs_buf_terminate(); | 1808 | xfs_buf_terminate(); |
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index bbe3d15a7904..2b830c2f322e 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h | |||
@@ -44,16 +44,6 @@ extern void xfs_qm_exit(void); | |||
44 | # define XFS_REALTIME_STRING | 44 | # define XFS_REALTIME_STRING |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #if XFS_BIG_BLKNOS | ||
48 | # if XFS_BIG_INUMS | ||
49 | # define XFS_BIGFS_STRING "large block/inode numbers, " | ||
50 | # else | ||
51 | # define XFS_BIGFS_STRING "large block numbers, " | ||
52 | # endif | ||
53 | #else | ||
54 | # define XFS_BIGFS_STRING | ||
55 | #endif | ||
56 | |||
57 | #ifdef DEBUG | 47 | #ifdef DEBUG |
58 | # define XFS_DBG_STRING "debug" | 48 | # define XFS_DBG_STRING "debug" |
59 | #else | 49 | #else |
@@ -64,7 +54,6 @@ extern void xfs_qm_exit(void); | |||
64 | #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ | 54 | #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ |
65 | XFS_SECURITY_STRING \ | 55 | XFS_SECURITY_STRING \ |
66 | XFS_REALTIME_STRING \ | 56 | XFS_REALTIME_STRING \ |
67 | XFS_BIGFS_STRING \ | ||
68 | XFS_DBG_STRING /* DBG must be last */ | 57 | XFS_DBG_STRING /* DBG must be last */ |
69 | 58 | ||
70 | struct xfs_inode; | 59 | struct xfs_inode; |
@@ -76,8 +65,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int); | |||
76 | 65 | ||
77 | extern void xfs_flush_inodes(struct xfs_mount *mp); | 66 | extern void xfs_flush_inodes(struct xfs_mount *mp); |
78 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | 67 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); |
79 | extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *); | 68 | extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount); |
80 | extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *); | 69 | extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount); |
81 | 70 | ||
82 | extern const struct export_operations xfs_export_operations; | 71 | extern const struct export_operations xfs_export_operations; |
83 | extern const struct xattr_handler *xfs_xattr_handlers[]; | 72 | extern const struct xattr_handler *xfs_xattr_handlers[]; |
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c new file mode 100644 index 000000000000..9835139ce1ec --- /dev/null +++ b/fs/xfs/xfs_sysfs.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Red Hat, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | #include "xfs.h" | ||
20 | #include "xfs_sysfs.h" | ||
21 | #include "xfs_log_format.h" | ||
22 | #include "xfs_log.h" | ||
23 | #include "xfs_log_priv.h" | ||
24 | |||
25 | struct xfs_sysfs_attr { | ||
26 | struct attribute attr; | ||
27 | ssize_t (*show)(char *buf, void *data); | ||
28 | ssize_t (*store)(const char *buf, size_t count, void *data); | ||
29 | }; | ||
30 | |||
31 | static inline struct xfs_sysfs_attr * | ||
32 | to_attr(struct attribute *attr) | ||
33 | { | ||
34 | return container_of(attr, struct xfs_sysfs_attr, attr); | ||
35 | } | ||
36 | |||
37 | #define XFS_SYSFS_ATTR_RW(name) \ | ||
38 | static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) | ||
39 | #define XFS_SYSFS_ATTR_RO(name) \ | ||
40 | static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) | ||
41 | |||
42 | #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr | ||
43 | |||
44 | /* | ||
45 | * xfs_mount kobject. This currently has no attributes and thus no need for show | ||
46 | * and store helpers. The mp kobject serves as the per-mount parent object that | ||
47 | * is identified by the fsname under sysfs. | ||
48 | */ | ||
49 | |||
50 | struct kobj_type xfs_mp_ktype = { | ||
51 | .release = xfs_sysfs_release, | ||
52 | }; | ||
53 | |||
54 | /* xlog */ | ||
55 | |||
56 | STATIC ssize_t | ||
57 | log_head_lsn_show( | ||
58 | char *buf, | ||
59 | void *data) | ||
60 | { | ||
61 | struct xlog *log = data; | ||
62 | int cycle; | ||
63 | int block; | ||
64 | |||
65 | spin_lock(&log->l_icloglock); | ||
66 | cycle = log->l_curr_cycle; | ||
67 | block = log->l_curr_block; | ||
68 | spin_unlock(&log->l_icloglock); | ||
69 | |||
70 | return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); | ||
71 | } | ||
72 | XFS_SYSFS_ATTR_RO(log_head_lsn); | ||
73 | |||
74 | STATIC ssize_t | ||
75 | log_tail_lsn_show( | ||
76 | char *buf, | ||
77 | void *data) | ||
78 | { | ||
79 | struct xlog *log = data; | ||
80 | int cycle; | ||
81 | int block; | ||
82 | |||
83 | xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); | ||
84 | return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); | ||
85 | } | ||
86 | XFS_SYSFS_ATTR_RO(log_tail_lsn); | ||
87 | |||
88 | STATIC ssize_t | ||
89 | reserve_grant_head_show( | ||
90 | char *buf, | ||
91 | void *data) | ||
92 | { | ||
93 | struct xlog *log = data; | ||
94 | int cycle; | ||
95 | int bytes; | ||
96 | |||
97 | xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes); | ||
98 | return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); | ||
99 | } | ||
100 | XFS_SYSFS_ATTR_RO(reserve_grant_head); | ||
101 | |||
102 | STATIC ssize_t | ||
103 | write_grant_head_show( | ||
104 | char *buf, | ||
105 | void *data) | ||
106 | { | ||
107 | struct xlog *log = data; | ||
108 | int cycle; | ||
109 | int bytes; | ||
110 | |||
111 | xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes); | ||
112 | return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); | ||
113 | } | ||
114 | XFS_SYSFS_ATTR_RO(write_grant_head); | ||
115 | |||
116 | static struct attribute *xfs_log_attrs[] = { | ||
117 | ATTR_LIST(log_head_lsn), | ||
118 | ATTR_LIST(log_tail_lsn), | ||
119 | ATTR_LIST(reserve_grant_head), | ||
120 | ATTR_LIST(write_grant_head), | ||
121 | NULL, | ||
122 | }; | ||
123 | |||
124 | static inline struct xlog * | ||
125 | to_xlog(struct kobject *kobject) | ||
126 | { | ||
127 | struct xfs_kobj *kobj = to_kobj(kobject); | ||
128 | return container_of(kobj, struct xlog, l_kobj); | ||
129 | } | ||
130 | |||
131 | STATIC ssize_t | ||
132 | xfs_log_show( | ||
133 | struct kobject *kobject, | ||
134 | struct attribute *attr, | ||
135 | char *buf) | ||
136 | { | ||
137 | struct xlog *log = to_xlog(kobject); | ||
138 | struct xfs_sysfs_attr *xfs_attr = to_attr(attr); | ||
139 | |||
140 | return xfs_attr->show ? xfs_attr->show(buf, log) : 0; | ||
141 | } | ||
142 | |||
143 | STATIC ssize_t | ||
144 | xfs_log_store( | ||
145 | struct kobject *kobject, | ||
146 | struct attribute *attr, | ||
147 | const char *buf, | ||
148 | size_t count) | ||
149 | { | ||
150 | struct xlog *log = to_xlog(kobject); | ||
151 | struct xfs_sysfs_attr *xfs_attr = to_attr(attr); | ||
152 | |||
153 | return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0; | ||
154 | } | ||
155 | |||
156 | static struct sysfs_ops xfs_log_ops = { | ||
157 | .show = xfs_log_show, | ||
158 | .store = xfs_log_store, | ||
159 | }; | ||
160 | |||
161 | struct kobj_type xfs_log_ktype = { | ||
162 | .release = xfs_sysfs_release, | ||
163 | .sysfs_ops = &xfs_log_ops, | ||
164 | .default_attrs = xfs_log_attrs, | ||
165 | }; | ||
diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h new file mode 100644 index 000000000000..54a2091183c0 --- /dev/null +++ b/fs/xfs/xfs_sysfs.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Red Hat, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | #ifndef __XFS_SYSFS_H__ | ||
20 | #define __XFS_SYSFS_H__ | ||
21 | |||
22 | extern struct kobj_type xfs_mp_ktype; /* xfs_mount */ | ||
23 | extern struct kobj_type xfs_log_ktype; /* xlog */ | ||
24 | |||
25 | static inline struct xfs_kobj * | ||
26 | to_kobj(struct kobject *kobject) | ||
27 | { | ||
28 | return container_of(kobject, struct xfs_kobj, kobject); | ||
29 | } | ||
30 | |||
31 | static inline void | ||
32 | xfs_sysfs_release(struct kobject *kobject) | ||
33 | { | ||
34 | struct xfs_kobj *kobj = to_kobj(kobject); | ||
35 | complete(&kobj->complete); | ||
36 | } | ||
37 | |||
38 | static inline int | ||
39 | xfs_sysfs_init( | ||
40 | struct xfs_kobj *kobj, | ||
41 | struct kobj_type *ktype, | ||
42 | struct xfs_kobj *parent_kobj, | ||
43 | const char *name) | ||
44 | { | ||
45 | init_completion(&kobj->complete); | ||
46 | return kobject_init_and_add(&kobj->kobject, ktype, | ||
47 | &parent_kobj->kobject, "%s", name); | ||
48 | } | ||
49 | |||
50 | static inline void | ||
51 | xfs_sysfs_del( | ||
52 | struct xfs_kobj *kobj) | ||
53 | { | ||
54 | kobject_del(&kobj->kobject); | ||
55 | kobject_put(&kobj->kobject); | ||
56 | wait_for_completion(&kobj->complete); | ||
57 | } | ||
58 | |||
59 | #endif /* __XFS_SYSFS_H__ */ | ||
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 65c6e6650b1a..b79dc66b2ecd 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h | |||
@@ -38,43 +38,18 @@ typedef __int32_t xfs_tid_t; /* transaction identifier */ | |||
38 | typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ | 38 | typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ |
39 | typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */ | 39 | typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */ |
40 | 40 | ||
41 | /* | ||
42 | * These types are 64 bits on disk but are either 32 or 64 bits in memory. | ||
43 | * Disk based types: | ||
44 | */ | ||
45 | typedef __uint64_t xfs_dfsbno_t; /* blockno in filesystem (agno|agbno) */ | ||
46 | typedef __uint64_t xfs_drfsbno_t; /* blockno in filesystem (raw) */ | ||
47 | typedef __uint64_t xfs_drtbno_t; /* extent (block) in realtime area */ | ||
48 | typedef __uint64_t xfs_dfiloff_t; /* block number in a file */ | ||
49 | typedef __uint64_t xfs_dfilblks_t; /* number of blocks in a file */ | ||
50 | |||
51 | /* | ||
52 | * Memory based types are conditional. | ||
53 | */ | ||
54 | #if XFS_BIG_BLKNOS | ||
55 | typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ | 41 | typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ |
56 | typedef __uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ | 42 | typedef __uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ |
57 | typedef __uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ | 43 | typedef __uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ |
58 | typedef __int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ | ||
59 | #else | ||
60 | typedef __uint32_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ | ||
61 | typedef __uint32_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ | ||
62 | typedef __uint32_t xfs_rtblock_t; /* extent (block) in realtime area */ | ||
63 | typedef __int32_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ | ||
64 | #endif | ||
65 | typedef __uint64_t xfs_fileoff_t; /* block number in a file */ | 44 | typedef __uint64_t xfs_fileoff_t; /* block number in a file */ |
66 | typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ | ||
67 | typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ | 45 | typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ |
68 | 46 | ||
47 | typedef __int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ | ||
48 | typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ | ||
69 | 49 | ||
70 | /* | 50 | /* |
71 | * Null values for the types. | 51 | * Null values for the types. |
72 | */ | 52 | */ |
73 | #define NULLDFSBNO ((xfs_dfsbno_t)-1) | ||
74 | #define NULLDRFSBNO ((xfs_drfsbno_t)-1) | ||
75 | #define NULLDRTBNO ((xfs_drtbno_t)-1) | ||
76 | #define NULLDFILOFF ((xfs_dfiloff_t)-1) | ||
77 | |||
78 | #define NULLFSBLOCK ((xfs_fsblock_t)-1) | 53 | #define NULLFSBLOCK ((xfs_fsblock_t)-1) |
79 | #define NULLRFSBLOCK ((xfs_rfsblock_t)-1) | 54 | #define NULLRFSBLOCK ((xfs_rfsblock_t)-1) |
80 | #define NULLRTBLOCK ((xfs_rtblock_t)-1) | 55 | #define NULLRTBLOCK ((xfs_rtblock_t)-1) |