* [PATCH 02/17] ufs: missing ->splice_write()
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 03/17] ufs: fix ufs_read_cylinder() failure handling Al Viro
` (14 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
normal ->write_iter()-based ->splice_write() works here just fine...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/file.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 6558882a89ef..487ad1fc2de6 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -42,4 +42,5 @@ const struct file_operations ufs_file_operations = {
.open = generic_file_open,
.fsync = generic_file_fsync,
.splice_read = filemap_splice_read,
+ .splice_write = iter_file_splice_write,
};
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 03/17] ufs: fix ufs_read_cylinder() failure handling
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
2024-10-18 23:19 ` [PATCH 02/17] ufs: missing ->splice_write() Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 04/17] ufs: untangle ubh_...block...() macros, part 1 Al Viro
` (13 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
1) ufs_load_cylinder() should return NULL on ufs_read_cylinder() failures.
ufs_error() is not enough. As it is, IO failure on attempt to read a part
of cylinder group metadata is likely to end up with an oops.
2) we drop the wrong buffer heads when undoing sb_bread() on IO failure
halfway through the read - we need to brelse() what we've got from
sb_bread(), TYVM...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/cylinder.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c
index 1abe5454de47..a2813270c303 100644
--- a/fs/ufs/cylinder.c
+++ b/fs/ufs/cylinder.c
@@ -26,7 +26,7 @@
* Read cylinder group into cache. The memory space for ufs_cg_private_info
* structure is already allocated during ufs_read_super.
*/
-static void ufs_read_cylinder (struct super_block * sb,
+static bool ufs_read_cylinder(struct super_block *sb,
unsigned cgno, unsigned bitmap_nr)
{
struct ufs_sb_info * sbi = UFS_SB(sb);
@@ -46,9 +46,11 @@ static void ufs_read_cylinder (struct super_block * sb,
* We have already the first fragment of cylinder group block in buffer
*/
UCPI_UBH(ucpi)->bh[0] = sbi->s_ucg[cgno];
- for (i = 1; i < UCPI_UBH(ucpi)->count; i++)
- if (!(UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i)))
+ for (i = 1; i < UCPI_UBH(ucpi)->count; i++) {
+ UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i);
+ if (!UCPI_UBH(ucpi)->bh[i])
goto failed;
+ }
sbi->s_cgno[bitmap_nr] = cgno;
ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
@@ -67,13 +69,14 @@ static void ufs_read_cylinder (struct super_block * sb,
ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff);
ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks);
UFSD("EXIT\n");
- return;
+ return true;
failed:
for (j = 1; j < i; j++)
- brelse (sbi->s_ucg[j]);
+ brelse(UCPI_UBH(ucpi)->bh[j]);
sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno);
+ return false;
}
/*
@@ -156,15 +159,14 @@ struct ufs_cg_private_info * ufs_load_cylinder (
UFSD("EXIT (FAILED)\n");
return NULL;
}
- else {
- UFSD("EXIT\n");
- return sbi->s_ucpi[cgno];
- }
} else {
- ufs_read_cylinder (sb, cgno, cgno);
- UFSD("EXIT\n");
- return sbi->s_ucpi[cgno];
+ if (unlikely(!ufs_read_cylinder (sb, cgno, cgno))) {
+ UFSD("EXIT (FAILED)\n");
+ return NULL;
+ }
}
+ UFSD("EXIT\n");
+ return sbi->s_ucpi[cgno];
}
/*
* Cylinder group number cg is in cache but it was not last used,
@@ -195,7 +197,10 @@ struct ufs_cg_private_info * ufs_load_cylinder (
sbi->s_ucpi[j] = sbi->s_ucpi[j-1];
}
sbi->s_ucpi[0] = ucpi;
- ufs_read_cylinder (sb, cgno, 0);
+ if (unlikely(!ufs_read_cylinder (sb, cgno, 0))) {
+ UFSD("EXIT (FAILED)\n");
+ return NULL;
+ }
}
UFSD("EXIT\n");
return sbi->s_ucpi[0];
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 04/17] ufs: untangle ubh_...block...() macros, part 1
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
2024-10-18 23:19 ` [PATCH 02/17] ufs: missing ->splice_write() Al Viro
2024-10-18 23:19 ` [PATCH 03/17] ufs: fix ufs_read_cylinder() failure handling Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 05/17] ufs: untangle ubh_...block...(), part 2 Al Viro
` (12 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
passing implicit argument to a macro by having it in a variable
with special name is Not Nice(tm); just pass it explicitly.
kill an unused macro, while we are at it...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 10 +++++-----
fs/ufs/util.h | 11 +++--------
2 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 53c11be2b2c1..e412ddcfda03 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -95,7 +95,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
* Trying to reassemble free fragments into block
*/
blkno = ufs_fragstoblks (bbase);
- if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
+ if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
uspi->cs_total.cs_nffree -= uspi->s_fpb;
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
@@ -182,10 +182,10 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
for (i = bit; i < end_bit; i += uspi->s_fpb) {
blkno = ufs_fragstoblks(i);
- if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
+ if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
ufs_error(sb, "ufs_free_blocks", "freeing free fragment");
}
- ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
+ ubh_setblock(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, 1);
@@ -716,7 +716,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
/*
* If the requested block is available, use it.
*/
- if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) {
+ if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) {
result = goal;
goto gotit;
}
@@ -730,7 +730,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
if (!try_add_frags(inode, uspi->s_fpb))
return 0;
blkno = ufs_fragstoblks(result);
- ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
+ ubh_clrblock(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, -1);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index bf708b68f150..729bc55398f2 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -455,10 +455,7 @@ static inline unsigned _ubh_find_last_zero_bit_(
return (base << uspi->s_bpfshift) + pos - begin;
}
-#define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block))
-
-#define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block)
-static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
+static inline int ubh_isblockset(struct ufs_sb_private_info * uspi,
struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
{
u8 mask;
@@ -478,8 +475,7 @@ static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
return 0;
}
-#define ubh_clrblock(ubh,begin,block) _ubh_clrblock_(uspi,ubh,begin,block)
-static inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi,
+static inline void ubh_clrblock(struct ufs_sb_private_info * uspi,
struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
{
switch (uspi->s_fpb) {
@@ -498,8 +494,7 @@ static inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi,
}
}
-#define ubh_setblock(ubh,begin,block) _ubh_setblock_(uspi,ubh,begin,block)
-static inline void _ubh_setblock_(struct ufs_sb_private_info * uspi,
+static inline void ubh_setblock(struct ufs_sb_private_info * uspi,
struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
{
switch (uspi->s_fpb) {
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 05/17] ufs: untangle ubh_...block...(), part 2
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (2 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 04/17] ufs: untangle ubh_...block...() macros, part 1 Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 06/17] ufs: untangle ubh_...block...(), part 3 Al Viro
` (11 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
pass cylinder group descriptor instead of its buffer head (ubh,
always UCPI_UBH(ucpi)) and its ->c_freeoff.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 10 +++++-----
fs/ufs/util.h | 16 +++++++++++-----
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index e412ddcfda03..d76c04fbd4fa 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -95,7 +95,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
* Trying to reassemble free fragments into block
*/
blkno = ufs_fragstoblks (bbase);
- if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
+ if (ubh_isblockset(uspi, ucpi, blkno)) {
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
uspi->cs_total.cs_nffree -= uspi->s_fpb;
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
@@ -182,10 +182,10 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
for (i = bit; i < end_bit; i += uspi->s_fpb) {
blkno = ufs_fragstoblks(i);
- if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
+ if (ubh_isblockset(uspi, ucpi, blkno)) {
ufs_error(sb, "ufs_free_blocks", "freeing free fragment");
}
- ubh_setblock(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
+ ubh_setblock(uspi, ucpi, blkno);
inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, 1);
@@ -716,7 +716,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
/*
* If the requested block is available, use it.
*/
- if (ubh_isblockset(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) {
+ if (ubh_isblockset(uspi, ucpi, ufs_fragstoblks(goal))) {
result = goal;
goto gotit;
}
@@ -730,7 +730,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
if (!try_add_frags(inode, uspi->s_fpb))
return 0;
blkno = ufs_fragstoblks(result);
- ubh_clrblock(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
+ ubh_clrblock(uspi, ucpi, blkno);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, -1);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 729bc55398f2..c7196a81fb0d 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -455,9 +455,11 @@ static inline unsigned _ubh_find_last_zero_bit_(
return (base << uspi->s_bpfshift) + pos - begin;
}
-static inline int ubh_isblockset(struct ufs_sb_private_info * uspi,
- struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
+static inline int ubh_isblockset(struct ufs_sb_private_info *uspi,
+ struct ufs_cg_private_info *ucpi, unsigned block)
{
+ struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
+ unsigned begin = ucpi->c_freeoff;
u8 mask;
switch (uspi->s_fpb) {
case 8:
@@ -475,9 +477,11 @@ static inline int ubh_isblockset(struct ufs_sb_private_info * uspi,
return 0;
}
-static inline void ubh_clrblock(struct ufs_sb_private_info * uspi,
- struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
+static inline void ubh_clrblock(struct ufs_sb_private_info *uspi,
+ struct ufs_cg_private_info *ucpi, unsigned block)
{
+ struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
+ unsigned begin = ucpi->c_freeoff;
switch (uspi->s_fpb) {
case 8:
*ubh_get_addr (ubh, begin + block) = 0x00;
@@ -495,8 +499,10 @@ static inline void ubh_clrblock(struct ufs_sb_private_info * uspi,
}
static inline void ubh_setblock(struct ufs_sb_private_info * uspi,
- struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
+ struct ufs_cg_private_info *ucpi, unsigned block)
{
+ struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
+ unsigned begin = ucpi->c_freeoff;
switch (uspi->s_fpb) {
case 8:
*ubh_get_addr(ubh, begin + block) = 0xff;
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 06/17] ufs: untangle ubh_...block...(), part 3
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (3 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 05/17] ufs: untangle ubh_...block...(), part 2 Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 07/17] ufs_clusteracct(): switch to passing fragment number Al Viro
` (10 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
Pass fragment number instead of a block one. It's available in all
callers and it makes the logics inside those helpers much simpler.
The bitmap they operate upon is with bit per fragment, block being
an aligned group of 1, 2, 4 or 8 adjacent fragments. We still
need a switch by the number of fragments in block (== number of
bits to check/set/clear), but finding the byte we need to work
with becomes uniform and that makes the things easier to follow.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 10 +++++-----
fs/ufs/util.h | 45 ++++++++++++++++++++++++---------------------
2 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index d76c04fbd4fa..7694666fac18 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -95,7 +95,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
* Trying to reassemble free fragments into block
*/
blkno = ufs_fragstoblks (bbase);
- if (ubh_isblockset(uspi, ucpi, blkno)) {
+ if (ubh_isblockset(uspi, ucpi, bbase)) {
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
uspi->cs_total.cs_nffree -= uspi->s_fpb;
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
@@ -182,10 +182,10 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
for (i = bit; i < end_bit; i += uspi->s_fpb) {
blkno = ufs_fragstoblks(i);
- if (ubh_isblockset(uspi, ucpi, blkno)) {
+ if (ubh_isblockset(uspi, ucpi, i)) {
ufs_error(sb, "ufs_free_blocks", "freeing free fragment");
}
- ubh_setblock(uspi, ucpi, blkno);
+ ubh_setblock(uspi, ucpi, i);
inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, 1);
@@ -716,7 +716,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
/*
* If the requested block is available, use it.
*/
- if (ubh_isblockset(uspi, ucpi, ufs_fragstoblks(goal))) {
+ if (ubh_isblockset(uspi, ucpi, goal)) {
result = goal;
goto gotit;
}
@@ -730,7 +730,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
if (!try_add_frags(inode, uspi->s_fpb))
return 0;
blkno = ufs_fragstoblks(result);
- ubh_clrblock(uspi, ucpi, blkno);
+ ubh_clrblock(uspi, ucpi, result);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, -1);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index c7196a81fb0d..fafae166ee55 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -456,65 +456,68 @@ static inline unsigned _ubh_find_last_zero_bit_(
}
static inline int ubh_isblockset(struct ufs_sb_private_info *uspi,
- struct ufs_cg_private_info *ucpi, unsigned block)
+ struct ufs_cg_private_info *ucpi, unsigned int frag)
{
struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
- unsigned begin = ucpi->c_freeoff;
+ u8 *p = ubh_get_addr(ubh, ucpi->c_freeoff + (frag >> 3));
u8 mask;
+
switch (uspi->s_fpb) {
case 8:
- return (*ubh_get_addr (ubh, begin + block) == 0xff);
+ return *p == 0xff;
case 4:
- mask = 0x0f << ((block & 0x01) << 2);
- return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask;
+ mask = 0x0f << (frag & 4);
+ return (*p & mask) == mask;
case 2:
- mask = 0x03 << ((block & 0x03) << 1);
- return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask;
+ mask = 0x03 << (frag & 6);
+ return (*p & mask) == mask;
case 1:
- mask = 0x01 << (block & 0x07);
- return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask;
+ mask = 0x01 << (frag & 7);
+ return (*p & mask) == mask;
}
return 0;
}
static inline void ubh_clrblock(struct ufs_sb_private_info *uspi,
- struct ufs_cg_private_info *ucpi, unsigned block)
+ struct ufs_cg_private_info *ucpi, unsigned int frag)
{
struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
- unsigned begin = ucpi->c_freeoff;
+ u8 *p = ubh_get_addr(ubh, ucpi->c_freeoff + (frag >> 3));
+
switch (uspi->s_fpb) {
case 8:
- *ubh_get_addr (ubh, begin + block) = 0x00;
+ *p = 0x00;
return;
case 4:
- *ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2));
+ *p &= ~(0x0f << (frag & 4));
return;
case 2:
- *ubh_get_addr (ubh, begin + (block >> 2)) &= ~(0x03 << ((block & 0x03) << 1));
+ *p &= ~(0x03 << (frag & 6));
return;
case 1:
- *ubh_get_addr (ubh, begin + (block >> 3)) &= ~(0x01 << ((block & 0x07)));
+ *p &= ~(0x01 << (frag & 7));
return;
}
}
static inline void ubh_setblock(struct ufs_sb_private_info * uspi,
- struct ufs_cg_private_info *ucpi, unsigned block)
+ struct ufs_cg_private_info *ucpi, unsigned int frag)
{
struct ufs_buffer_head *ubh = UCPI_UBH(ucpi);
- unsigned begin = ucpi->c_freeoff;
+ u8 *p = ubh_get_addr(ubh, ucpi->c_freeoff + (frag >> 3));
+
switch (uspi->s_fpb) {
case 8:
- *ubh_get_addr(ubh, begin + block) = 0xff;
+ *p = 0xff;
return;
case 4:
- *ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2));
+ *p |= 0x0f << (frag & 4);
return;
case 2:
- *ubh_get_addr(ubh, begin + (block >> 2)) |= (0x03 << ((block & 0x03) << 1));
+ *p |= 0x03 << (frag & 6);
return;
case 1:
- *ubh_get_addr(ubh, begin + (block >> 3)) |= (0x01 << ((block & 0x07)));
+ *p |= 0x01 << (frag & 7);
return;
}
}
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 07/17] ufs_clusteracct(): switch to passing fragment number
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (4 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 06/17] ufs: untangle ubh_...block...(), part 3 Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 08/17] ufs_free_fragments(): fix the braino in sanity check Al Viro
` (9 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
Currently all callers pass it a block number. All of them have it derived
from a fragment number (both fragment and block numbers are within a cylinder
group, and thus 32bit). Pass it the fragment number instead; none of the
callers has other uses for the block number, so that ends up with cleaner
code.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 7694666fac18..1793ce48df0a 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -43,7 +43,6 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
unsigned cgno, bit, end_bit, bbase, blkmap, i;
- u64 blkno;
sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
@@ -94,13 +93,12 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
/*
* Trying to reassemble free fragments into block
*/
- blkno = ufs_fragstoblks (bbase);
if (ubh_isblockset(uspi, ucpi, bbase)) {
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
uspi->cs_total.cs_nffree -= uspi->s_fpb;
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct (sb, ucpi, blkno, 1);
+ ufs_clusteracct(sb, ucpi, bbase, 1);
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
uspi->cs_total.cs_nbfree++;
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
@@ -139,7 +137,6 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
unsigned overflow, cgno, bit, end_bit, i;
- u64 blkno;
sb = inode->i_sb;
uspi = UFS_SB(sb)->s_uspi;
@@ -181,14 +178,13 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
}
for (i = bit; i < end_bit; i += uspi->s_fpb) {
- blkno = ufs_fragstoblks(i);
if (ubh_isblockset(uspi, ucpi, i)) {
ufs_error(sb, "ufs_free_blocks", "freeing free fragment");
}
ubh_setblock(uspi, ucpi, i);
inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct (sb, ucpi, blkno, 1);
+ ufs_clusteracct(sb, ucpi, i, 1);
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
uspi->cs_total.cs_nbfree++;
@@ -698,7 +694,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct ufs_cylinder_group * ucg;
- u64 result, blkno;
+ u64 result;
UFSD("ENTER, goal %llu\n", (unsigned long long)goal);
@@ -729,10 +725,9 @@ static u64 ufs_alloccg_block(struct inode *inode,
gotit:
if (!try_add_frags(inode, uspi->s_fpb))
return 0;
- blkno = ufs_fragstoblks(result);
ubh_clrblock(uspi, ucpi, result);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct (sb, ucpi, blkno, -1);
+ ufs_clusteracct(sb, ucpi, result, -1);
fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);
uspi->cs_total.cs_nbfree--;
@@ -863,12 +858,12 @@ static u64 ufs_bitmap_search(struct super_block *sb,
}
static void ufs_clusteracct(struct super_block * sb,
- struct ufs_cg_private_info * ucpi, unsigned blkno, int cnt)
+ struct ufs_cg_private_info * ucpi, unsigned frag, int cnt)
{
- struct ufs_sb_private_info * uspi;
+ struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi;
int i, start, end, forw, back;
+ unsigned blkno = ufs_fragstoblks(frag);
- uspi = UFS_SB(sb)->s_uspi;
if (uspi->s_contigsumsize <= 0)
return;
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 08/17] ufs_free_fragments(): fix the braino in sanity check
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (5 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 07/17] ufs_clusteracct(): switch to passing fragment number Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 09/17] ufs_inode_getfrag(): remove junk comment Al Viro
` (8 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
The function expects that all fragments it's been asked to free will
be within the same block. And it even has a sanity check verifying
that - it takes the fragment number modulo the number of fragments
per block, adds the count and checks if that's too high.
Unfortunately, it misspells the upper limit - instead of ->s_fpb
(fragments per block) it says ->s_fpg (fragments per cylinder group).
So "too high" ends up being insanely lenient.
Had been that way since 2.1.112, when UFS write support had been
added. 27 years to spot a typo...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 1793ce48df0a..82f1a4a128a2 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -50,7 +50,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
UFSD("ENTER, fragment %llu, count %u\n",
(unsigned long long)fragment, count);
- if (ufs_fragnum(fragment) + count > uspi->s_fpg)
+ if (ufs_fragnum(fragment) + count > uspi->s_fpb)
ufs_error (sb, "ufs_free_fragments", "internal error");
mutex_lock(&UFS_SB(sb)->s_lock);
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 09/17] ufs_inode_getfrag(): remove junk comment
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (6 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 08/17] ufs_free_fragments(): fix the braino in sanity check Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 10/17] ufs: get rid of ubh_{ubhcpymem,memcpyubh}() Al Viro
` (7 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
It used to be a stubbed out beginning of ufs2 support, which had
been implemented differently quite a while ago. Remove the
commented-out (pseudo-)code.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/inode.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 5331ae7ebf3e..71d28561200f 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -264,11 +264,6 @@ ufs_inode_getfrag(struct inode *inode, unsigned index,
unsigned nfrags = uspi->s_fpb;
void *p;
- /* TODO : to be done for write support
- if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
- goto ufs2;
- */
-
p = ufs_get_direct_data_ptr(uspi, ufsi, index);
tmp = ufs_data_ptr_to_cpu(sb, p);
if (tmp)
@@ -303,21 +298,6 @@ ufs_inode_getfrag(struct inode *inode, unsigned index,
mark_inode_dirty(inode);
out:
return tmp + uspi->s_sbbase;
-
- /* This part : To be implemented ....
- Required only for writing, not required for READ-ONLY.
-ufs2:
-
- u2_block = ufs_fragstoblks(fragment);
- u2_blockoff = ufs_fragnum(fragment);
- p = ufsi->i_u1.u2_i_data + block;
- goal = 0;
-
-repeat2:
- tmp = fs32_to_cpu(sb, *p);
- lastfrag = ufsi->i_lastfrag;
-
- */
}
/**
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 10/17] ufs: get rid of ubh_{ubhcpymem,memcpyubh}()
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (7 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 09/17] ufs_inode_getfrag(): remove junk comment Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 11/17] clean ufs_trunc_direct() up a bit Al Viro
` (6 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
used only in ufs_read_cylinder_structures()/ufs_put_super_internal()
and there we can just as well avoid bothering with ufs_buffer_head
and just deal with it fragment-by-fragment.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/super.c | 45 +++++++++++++++++----------------------------
fs/ufs/util.c | 46 ----------------------------------------------
fs/ufs/util.h | 5 -----
3 files changed, 17 insertions(+), 79 deletions(-)
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index bc625788589c..e876c60e70ea 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -505,7 +505,6 @@ static int ufs_read_cylinder_structures(struct super_block *sb)
{
struct ufs_sb_info *sbi = UFS_SB(sb);
struct ufs_sb_private_info *uspi = sbi->s_uspi;
- struct ufs_buffer_head * ubh;
unsigned char * base, * space;
unsigned size, blks, i;
@@ -521,21 +520,13 @@ static int ufs_read_cylinder_structures(struct super_block *sb)
if (!base)
goto failed;
sbi->s_csp = (struct ufs_csum *)space;
- for (i = 0; i < blks; i += uspi->s_fpb) {
- size = uspi->s_bsize;
- if (i + uspi->s_fpb > blks)
- size = (blks - i) * uspi->s_fsize;
-
- ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
-
- if (!ubh)
+ for (i = 0; i < blks; i++) {
+ struct buffer_head *bh = sb_bread(sb, uspi->s_csaddr + i);
+ if (!bh)
goto failed;
-
- ubh_ubhcpymem (space, ubh, size);
-
- space += size;
- ubh_brelse (ubh);
- ubh = NULL;
+ memcpy(space, bh->b_data, uspi->s_fsize);
+ space += uspi->s_fsize;
+ brelse (bh);
}
/*
@@ -645,7 +636,6 @@ static void ufs_put_super_internal(struct super_block *sb)
{
struct ufs_sb_info *sbi = UFS_SB(sb);
struct ufs_sb_private_info *uspi = sbi->s_uspi;
- struct ufs_buffer_head * ubh;
unsigned char * base, * space;
unsigned blks, size, i;
@@ -656,18 +646,17 @@ static void ufs_put_super_internal(struct super_block *sb)
size = uspi->s_cssize;
blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
base = space = (char*) sbi->s_csp;
- for (i = 0; i < blks; i += uspi->s_fpb) {
- size = uspi->s_bsize;
- if (i + uspi->s_fpb > blks)
- size = (blks - i) * uspi->s_fsize;
-
- ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
-
- ubh_memcpyubh (ubh, space, size);
- space += size;
- ubh_mark_buffer_uptodate (ubh, 1);
- ubh_mark_buffer_dirty (ubh);
- ubh_brelse (ubh);
+ for (i = 0; i < blks; i++, space += uspi->s_fsize) {
+ struct buffer_head *bh = sb_bread(sb, uspi->s_csaddr + i);
+
+ if (unlikely(!bh)) { // better than an oops...
+ ufs_panic(sb, __func__,
+ "can't write part of cylinder group summary");
+ continue;
+ }
+ memcpy(bh->b_data, space, uspi->s_fsize);
+ mark_buffer_dirty(bh);
+ brelse(bh);
}
for (i = 0; i < sbi->s_cg_loaded; i++) {
ufs_put_cylinder (sb, i);
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 2acf191eb89e..f0e906ab4ddd 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -99,20 +99,6 @@ void ubh_mark_buffer_dirty (struct ufs_buffer_head * ubh)
mark_buffer_dirty (ubh->bh[i]);
}
-void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag)
-{
- unsigned i;
- if (!ubh)
- return;
- if (flag) {
- for ( i = 0; i < ubh->count; i++ )
- set_buffer_uptodate (ubh->bh[i]);
- } else {
- for ( i = 0; i < ubh->count; i++ )
- clear_buffer_uptodate (ubh->bh[i]);
- }
-}
-
void ubh_sync_block(struct ufs_buffer_head *ubh)
{
if (ubh) {
@@ -146,38 +132,6 @@ int ubh_buffer_dirty (struct ufs_buffer_head * ubh)
return result;
}
-void _ubh_ubhcpymem_(struct ufs_sb_private_info * uspi,
- unsigned char * mem, struct ufs_buffer_head * ubh, unsigned size)
-{
- unsigned len, bhno;
- if (size > (ubh->count << uspi->s_fshift))
- size = ubh->count << uspi->s_fshift;
- bhno = 0;
- while (size) {
- len = min_t(unsigned int, size, uspi->s_fsize);
- memcpy (mem, ubh->bh[bhno]->b_data, len);
- mem += uspi->s_fsize;
- size -= len;
- bhno++;
- }
-}
-
-void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi,
- struct ufs_buffer_head * ubh, unsigned char * mem, unsigned size)
-{
- unsigned len, bhno;
- if (size > (ubh->count << uspi->s_fshift))
- size = ubh->count << uspi->s_fshift;
- bhno = 0;
- while (size) {
- len = min_t(unsigned int, size, uspi->s_fsize);
- memcpy (ubh->bh[bhno]->b_data, mem, len);
- mem += uspi->s_fsize;
- size -= len;
- bhno++;
- }
-}
-
dev_t
ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi)
{
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index fafae166ee55..391bb4f11d74 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -263,14 +263,9 @@ extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, str
extern void ubh_brelse (struct ufs_buffer_head *);
extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);
-extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
extern void ubh_sync_block(struct ufs_buffer_head *);
extern void ubh_bforget (struct ufs_buffer_head *);
extern int ubh_buffer_dirty (struct ufs_buffer_head *);
-#define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size)
-extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struct ufs_buffer_head *, unsigned);
-#define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size)
-extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
/* This functions works with cache pages*/
struct folio *ufs_get_locked_folio(struct address_space *mapping, pgoff_t index);
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 11/17] clean ufs_trunc_direct() up a bit...
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (8 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 10/17] ufs: get rid of ubh_{ubhcpymem,memcpyubh}() Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 12/17] ufs: take the handling of free block counters into a helper Al Viro
` (5 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
For short files (== no indirect blocks needed) UFS allows the last
block to be a partial one. That creates some complications for
truncation down to "short file" lengths. ufs_trunc_direct() is
called when we'd already made sure that new EOF is not in a hole;
nothing needs to be done if we are extending the file and in
case we are shrinking the file it needs to
* shrink or free the old final block.
* free all full direct blocks between the new and old EOF.
* possibly shrink the new final block.
The logics is needlessly complicated by trying to keep all cases
handled by the same sequence of operations.
if not shrinking
nothing to do
else if number of full blocks unchanged
free the tail of possibly partial last block
else
free the tail of (currently full) new last block
free all present (full) blocks in between
free the (possibly partial) old last block
is easier to follow than the result of trying to unify these
cases.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/inode.c | 129 +++++++++++++++++++++++--------------------------
1 file changed, 61 insertions(+), 68 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 71d28561200f..a3475afb3c26 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -878,91 +878,84 @@ static inline void free_data(struct to_free *ctx, u64 from, unsigned count)
#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
+/*
+ * used only for truncation down to direct blocks.
+ */
static void ufs_trunc_direct(struct inode *inode)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
- struct super_block * sb;
- struct ufs_sb_private_info * uspi;
- void *p;
- u64 frag1, frag2, frag3, frag4, block1, block2;
+ struct super_block *sb = inode->i_sb;
+ struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+ unsigned int new_frags, old_frags;
+ unsigned int old_slot, new_slot;
+ unsigned int old_tail, new_tail;
struct to_free ctx = {.inode = inode};
- unsigned i, tmp;
UFSD("ENTER: ino %lu\n", inode->i_ino);
- sb = inode->i_sb;
- uspi = UFS_SB(sb)->s_uspi;
-
- frag1 = DIRECT_FRAGMENT;
- frag4 = min_t(u64, UFS_NDIR_FRAGMENT, ufsi->i_lastfrag);
- frag2 = ((frag1 & uspi->s_fpbmask) ? ((frag1 | uspi->s_fpbmask) + 1) : frag1);
- frag3 = frag4 & ~uspi->s_fpbmask;
- block1 = block2 = 0;
- if (frag2 > frag3) {
- frag2 = frag4;
- frag3 = frag4 = 0;
- } else if (frag2 < frag3) {
- block1 = ufs_fragstoblks (frag2);
- block2 = ufs_fragstoblks (frag3);
- }
-
- UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu,"
- " frag3 %llu, frag4 %llu\n", inode->i_ino,
- (unsigned long long)frag1, (unsigned long long)frag2,
- (unsigned long long)block1, (unsigned long long)block2,
- (unsigned long long)frag3, (unsigned long long)frag4);
+ new_frags = DIRECT_FRAGMENT;
+ // new_frags = first fragment past the new EOF
+ old_frags = min_t(u64, UFS_NDIR_FRAGMENT, ufsi->i_lastfrag);
+ // old_frags = first fragment past the old EOF or covered by indirects
- if (frag1 >= frag2)
- goto next1;
-
- /*
- * Free first free fragments
- */
- p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag1));
- tmp = ufs_data_ptr_to_cpu(sb, p);
- if (!tmp )
- ufs_panic (sb, "ufs_trunc_direct", "internal error");
- frag2 -= frag1;
- frag1 = ufs_fragnum (frag1);
+ if (new_frags >= old_frags) // expanding - nothing to free
+ goto done;
- ufs_free_fragments(inode, tmp + frag1, frag2);
+ old_tail = ufs_fragnum(old_frags);
+ old_slot = ufs_fragstoblks(old_frags);
+ new_tail = ufs_fragnum(new_frags);
+ new_slot = ufs_fragstoblks(new_frags);
-next1:
- /*
- * Free whole blocks
- */
- for (i = block1 ; i < block2; i++) {
- p = ufs_get_direct_data_ptr(uspi, ufsi, i);
- tmp = ufs_data_ptr_to_cpu(sb, p);
+ if (old_slot == new_slot) { // old_tail > 0
+ void *p = ufs_get_direct_data_ptr(uspi, ufsi, old_slot);
+ u64 tmp = ufs_data_ptr_to_cpu(sb, p);
if (!tmp)
- continue;
- write_seqlock(&ufsi->meta_lock);
- ufs_data_ptr_clear(uspi, p);
- write_sequnlock(&ufsi->meta_lock);
+ ufs_panic(sb, __func__, "internal error");
+ if (!new_tail) {
+ write_seqlock(&ufsi->meta_lock);
+ ufs_data_ptr_clear(uspi, p);
+ write_sequnlock(&ufsi->meta_lock);
+ }
+ ufs_free_fragments(inode, tmp + new_tail, old_tail - new_tail);
+ } else {
+ unsigned int slot = new_slot;
- free_data(&ctx, tmp, uspi->s_fpb);
- }
+ if (new_tail) {
+ void *p = ufs_get_direct_data_ptr(uspi, ufsi, slot++);
+ u64 tmp = ufs_data_ptr_to_cpu(sb, p);
+ if (!tmp)
+ ufs_panic(sb, __func__, "internal error");
- free_data(&ctx, 0, 0);
+ ufs_free_fragments(inode, tmp + new_tail,
+ uspi->s_fpb - new_tail);
+ }
+ while (slot < old_slot) {
+ void *p = ufs_get_direct_data_ptr(uspi, ufsi, slot++);
+ u64 tmp = ufs_data_ptr_to_cpu(sb, p);
+ if (!tmp)
+ continue;
+ write_seqlock(&ufsi->meta_lock);
+ ufs_data_ptr_clear(uspi, p);
+ write_sequnlock(&ufsi->meta_lock);
- if (frag3 >= frag4)
- goto next3;
+ free_data(&ctx, tmp, uspi->s_fpb);
+ }
- /*
- * Free last free fragments
- */
- p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag3));
- tmp = ufs_data_ptr_to_cpu(sb, p);
- if (!tmp )
- ufs_panic(sb, "ufs_truncate_direct", "internal error");
- frag4 = ufs_fragnum (frag4);
- write_seqlock(&ufsi->meta_lock);
- ufs_data_ptr_clear(uspi, p);
- write_sequnlock(&ufsi->meta_lock);
+ free_data(&ctx, 0, 0);
- ufs_free_fragments (inode, tmp, frag4);
- next3:
+ if (old_tail) {
+ void *p = ufs_get_direct_data_ptr(uspi, ufsi, slot);
+ u64 tmp = ufs_data_ptr_to_cpu(sb, p);
+ if (!tmp)
+ ufs_panic(sb, __func__, "internal error");
+ write_seqlock(&ufsi->meta_lock);
+ ufs_data_ptr_clear(uspi, p);
+ write_sequnlock(&ufsi->meta_lock);
+ ufs_free_fragments(inode, tmp, old_tail);
+ }
+ }
+done:
UFSD("EXIT: ino %lu\n", inode->i_ino);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 12/17] ufs: take the handling of free block counters into a helper
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (9 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 11/17] clean ufs_trunc_direct() up a bit Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 13/17] ufs: Convert ufs_inode_getblock() to take a folio Al Viro
` (4 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
There are 3 places where those counters (many and varied...) are
adjusted - when we are freeing fragments and get an entire block
freed, when we are freeing blocks and (in opposite direction) when
we are grabbing a block. The logics is identical (modulo the
sign of adjustment) in all three; better take it into a helper -
less duplication and less clutter in the callers that way.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 66 +++++++++++++++++++------------------------------
1 file changed, 26 insertions(+), 40 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 82f1a4a128a2..c60006c5806c 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -33,6 +33,29 @@ static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *
static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[];
static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int);
+static void adjust_free_blocks(struct super_block *sb,
+ struct ufs_cylinder_group *ucg,
+ struct ufs_cg_private_info *ucpi,
+ unsigned fragment, int delta)
+{
+ struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+
+ if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
+ ufs_clusteracct(sb, ucpi, fragment, delta);
+
+ fs32_add(sb, &ucg->cg_cs.cs_nbfree, delta);
+ uspi->cs_total.cs_nbfree += delta;
+ fs32_add(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, delta);
+
+ if (uspi->fs_magic != UFS2_MAGIC) {
+ unsigned cylno = ufs_cbtocylno(fragment);
+
+ fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
+ ufs_cbtorpos(fragment)), delta);
+ fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), delta);
+ }
+}
+
/*
* Free 'count' fragments from fragment number 'fragment'
*/
@@ -97,18 +120,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
uspi->cs_total.cs_nffree -= uspi->s_fpb;
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
- if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct(sb, ucpi, bbase, 1);
- fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
- uspi->cs_total.cs_nbfree++;
- fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
- if (uspi->fs_magic != UFS2_MAGIC) {
- unsigned cylno = ufs_cbtocylno (bbase);
-
- fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
- ufs_cbtorpos(bbase)), 1);
- fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
- }
+ adjust_free_blocks(sb, ucg, ucpi, bbase, 1);
}
ubh_mark_buffer_dirty (USPI_UBH(uspi));
@@ -183,20 +195,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
}
ubh_setblock(uspi, ucpi, i);
inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift);
- if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct(sb, ucpi, i, 1);
-
- fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
- uspi->cs_total.cs_nbfree++;
- fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
-
- if (uspi->fs_magic != UFS2_MAGIC) {
- unsigned cylno = ufs_cbtocylno(i);
-
- fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
- ufs_cbtorpos(i)), 1);
- fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
- }
+ adjust_free_blocks(sb, ucg, ucpi, i, 1);
}
ubh_mark_buffer_dirty (USPI_UBH(uspi));
@@ -726,20 +725,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
if (!try_add_frags(inode, uspi->s_fpb))
return 0;
ubh_clrblock(uspi, ucpi, result);
- if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
- ufs_clusteracct(sb, ucpi, result, -1);
-
- fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);
- uspi->cs_total.cs_nbfree--;
- fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1);
-
- if (uspi->fs_magic != UFS2_MAGIC) {
- unsigned cylno = ufs_cbtocylno((unsigned)result);
-
- fs16_sub(sb, &ubh_cg_blks(ucpi, cylno,
- ufs_cbtorpos((unsigned)result)), 1);
- fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1);
- }
+ adjust_free_blocks(sb, ucg, ucpi, result, -1);
UFSD("EXIT, result %llu\n", (unsigned long long)result);
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 13/17] ufs: Convert ufs_inode_getblock() to take a folio
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (10 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 12/17] ufs: take the handling of free block counters into a helper Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 14/17] ufs: Convert ufs_extend_tail() " Al Viro
` (3 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Pass bh->b_folio instead of bh->b_page. They're in a union, so no
code change expected.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/inode.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index a3475afb3c26..912950ee5104 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -309,12 +309,11 @@ ufs_inode_getfrag(struct inode *inode, unsigned index,
* (block will hold this fragment and also uspi->s_fpb-1)
* @err: see ufs_inode_getfrag()
* @new: see ufs_inode_getfrag()
- * @locked_page: see ufs_inode_getfrag()
+ * @locked_folio: see ufs_inode_getfrag()
*/
-static u64
-ufs_inode_getblock(struct inode *inode, u64 ind_block,
- unsigned index, sector_t new_fragment, int *err,
- int *new, struct page *locked_page)
+static u64 ufs_inode_getblock(struct inode *inode, u64 ind_block,
+ unsigned index, sector_t new_fragment, int *err,
+ int *new, struct folio *locked_folio)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
@@ -349,7 +348,7 @@ ufs_inode_getblock(struct inode *inode, u64 ind_block,
else
goal = bh->b_blocknr + uspi->s_fpb;
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal,
- uspi->s_fpb, err, locked_page);
+ uspi->s_fpb, err, &locked_folio->page);
if (!tmp)
goto out;
@@ -430,7 +429,7 @@ static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buff
phys64 = ufs_inode_getblock(inode, phys64, offsets[i],
fragment, &err, NULL, NULL);
phys64 = ufs_inode_getblock(inode, phys64, offsets[depth - 1],
- fragment, &err, &new, bh_result->b_page);
+ fragment, &err, &new, bh_result->b_folio);
}
out:
if (phys64) {
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 14/17] ufs: Convert ufs_extend_tail() to take a folio
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (11 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 13/17] ufs: Convert ufs_inode_getblock() to take a folio Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 15/17] ufs: Convert ufs_inode_getfrag() " Al Viro
` (2 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Pass bh->b_folio instead of bh->b_page. They're in a union, so no
code change expected.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/inode.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 912950ee5104..1d3eb485df41 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -220,7 +220,7 @@ static u64 ufs_frag_map(struct inode *inode, unsigned offsets[4], int depth)
*/
static bool
ufs_extend_tail(struct inode *inode, u64 writes_to,
- int *err, struct page *locked_page)
+ int *err, struct folio *locked_folio)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -239,7 +239,7 @@ ufs_extend_tail(struct inode *inode, u64 writes_to,
p = ufs_get_direct_data_ptr(uspi, ufsi, block);
tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p),
new_size - (lastfrag & uspi->s_fpbmask), err,
- locked_page);
+ &locked_folio->page);
return tmp != 0;
}
@@ -413,7 +413,7 @@ static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buff
unsigned tailfrags = lastfrag & uspi->s_fpbmask;
if (tailfrags && fragment >= lastfrag) {
if (!ufs_extend_tail(inode, fragment,
- &err, bh_result->b_page))
+ &err, bh_result->b_folio))
goto out;
}
}
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 15/17] ufs: Convert ufs_inode_getfrag() to take a folio
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (12 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 14/17] ufs: Convert ufs_extend_tail() " Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 16/17] ufs: Pass a folio to ufs_new_fragments() Al Viro
2024-10-18 23:19 ` [PATCH 17/17] ufs: Convert ufs_change_blocknr() to take a folio Al Viro
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Pass bh->b_folio instead of bh->b_page. They're in a union, so no
code change expected.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/inode.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 1d3eb485df41..30e5d695d74d 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -252,10 +252,9 @@ ufs_extend_tail(struct inode *inode, u64 writes_to,
* @new: we set it if we allocate new block
* @locked_page: for ufs_new_fragments()
*/
-static u64
-ufs_inode_getfrag(struct inode *inode, unsigned index,
+static u64 ufs_inode_getfrag(struct inode *inode, unsigned index,
sector_t new_fragment, int *err,
- int *new, struct page *locked_page)
+ int *new, struct folio *locked_folio)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -283,7 +282,7 @@ ufs_inode_getfrag(struct inode *inode, unsigned index,
goal += uspi->s_fpb;
}
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment),
- goal, nfrags, err, locked_page);
+ goal, nfrags, err, &locked_folio->page);
if (!tmp) {
*err = -ENOSPC;
@@ -420,7 +419,7 @@ static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buff
if (depth == 1) {
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
- &err, &new, bh_result->b_page);
+ &err, &new, bh_result->b_folio);
} else {
int i;
phys64 = ufs_inode_getfrag(inode, offsets[0], fragment,
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 16/17] ufs: Pass a folio to ufs_new_fragments()
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (13 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 15/17] ufs: Convert ufs_inode_getfrag() " Al Viro
@ 2024-10-18 23:19 ` Al Viro
2024-10-18 23:19 ` [PATCH 17/17] ufs: Convert ufs_change_blocknr() to take a folio Al Viro
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
All callers now have a folio, pass it to ufs_new_fragments() instead
of converting back to a page.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 10 +++++-----
fs/ufs/inode.c | 8 ++++----
fs/ufs/ufs.h | 8 ++++----
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index c60006c5806c..e578e429c5d8 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -332,7 +332,7 @@ static void ufs_clear_frags(struct inode *inode, sector_t beg, unsigned int n,
u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
u64 goal, unsigned count, int *err,
- struct page *locked_page)
+ struct folio *locked_folio)
{
struct super_block * sb;
struct ufs_sb_private_info * uspi;
@@ -412,7 +412,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
result = ufs_alloc_fragments (inode, cgno, goal, count, err);
if (result) {
ufs_clear_frags(inode, result + oldcount,
- newcount - oldcount, locked_page != NULL);
+ newcount - oldcount, locked_folio != NULL);
*err = 0;
write_seqlock(&UFS_I(inode)->meta_lock);
ufs_cpu_to_data_ptr(sb, p, result);
@@ -436,7 +436,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
fragment + count);
read_sequnlock_excl(&UFS_I(inode)->meta_lock);
ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
- locked_page != NULL);
+ locked_folio != NULL);
mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT, result %llu\n", (unsigned long long)result);
return result;
@@ -457,11 +457,11 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
result = ufs_alloc_fragments (inode, cgno, goal, request, err);
if (result) {
ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
- locked_page != NULL);
+ locked_folio != NULL);
mutex_unlock(&UFS_SB(sb)->s_lock);
ufs_change_blocknr(inode, fragment - oldcount, oldcount,
uspi->s_sbbase + tmp,
- uspi->s_sbbase + result, locked_page);
+ uspi->s_sbbase + result, &locked_folio->page);
*err = 0;
write_seqlock(&UFS_I(inode)->meta_lock);
ufs_cpu_to_data_ptr(sb, p, result);
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 30e5d695d74d..7dc38fdef2ea 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -239,7 +239,7 @@ ufs_extend_tail(struct inode *inode, u64 writes_to,
p = ufs_get_direct_data_ptr(uspi, ufsi, block);
tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p),
new_size - (lastfrag & uspi->s_fpbmask), err,
- &locked_folio->page);
+ locked_folio);
return tmp != 0;
}
@@ -250,7 +250,7 @@ ufs_extend_tail(struct inode *inode, u64 writes_to,
* @new_fragment: number of new allocated fragment(s)
* @err: we set it if something wrong
* @new: we set it if we allocate new block
- * @locked_page: for ufs_new_fragments()
+ * @locked_folio: for ufs_new_fragments()
*/
static u64 ufs_inode_getfrag(struct inode *inode, unsigned index,
sector_t new_fragment, int *err,
@@ -282,7 +282,7 @@ static u64 ufs_inode_getfrag(struct inode *inode, unsigned index,
goal += uspi->s_fpb;
}
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment),
- goal, nfrags, err, &locked_folio->page);
+ goal, nfrags, err, locked_folio);
if (!tmp) {
*err = -ENOSPC;
@@ -347,7 +347,7 @@ static u64 ufs_inode_getblock(struct inode *inode, u64 ind_block,
else
goal = bh->b_blocknr + uspi->s_fpb;
tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal,
- uspi->s_fpb, err, &locked_folio->page);
+ uspi->s_fpb, err, locked_folio);
if (!tmp)
goto out;
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index c7638e62ffe8..e7df65dd4351 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -88,10 +88,10 @@ struct ufs_inode_info {
#endif
/* balloc.c */
-extern void ufs_free_fragments (struct inode *, u64, unsigned);
-extern void ufs_free_blocks (struct inode *, u64, unsigned);
-extern u64 ufs_new_fragments(struct inode *, void *, u64, u64,
- unsigned, int *, struct page *);
+void ufs_free_fragments (struct inode *, u64 fragment, unsigned count);
+void ufs_free_blocks (struct inode *, u64 fragment, unsigned count);
+u64 ufs_new_fragments(struct inode *, void *, u64 fragment, u64 goal,
+ unsigned count, int *err, struct folio *);
/* cylinder.c */
extern struct ufs_cg_private_info * ufs_load_cylinder (struct super_block *, unsigned);
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 17/17] ufs: Convert ufs_change_blocknr() to take a folio
2024-10-18 23:19 ` [PATCH 01/17] ufs: fix handling of delete_entry and set_link failures Al Viro
` (14 preceding siblings ...)
2024-10-18 23:19 ` [PATCH 16/17] ufs: Pass a folio to ufs_new_fragments() Al Viro
@ 2024-10-18 23:19 ` Al Viro
15 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-10-18 23:19 UTC (permalink / raw)
To: linux-fsdevel
Cc: Evgeniy Dushistov, Matthew Wilcox, Christian Brauner, Jan Kara
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Now that ufs_new_fragments() has a folio, pass it to ufs_change_blocknr()
as a folio instead of converting it from folio to page to folio.
This removes the last use of struct page in UFS.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ufs/balloc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index e578e429c5d8..194ed3ab945e 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -229,13 +229,13 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
* situated at the end of file.
*
* We can come here from ufs_writepage or ufs_prepare_write,
- * locked_page is argument of these functions, so we already lock it.
+ * locked_folio is argument of these functions, so we already lock it.
*/
static void ufs_change_blocknr(struct inode *inode, sector_t beg,
unsigned int count, sector_t oldb,
- sector_t newb, struct page *locked_page)
+ sector_t newb, struct folio *locked_folio)
{
- struct folio *folio, *locked_folio = page_folio(locked_page);
+ struct folio *folio;
const unsigned blks_per_page =
1 << (PAGE_SHIFT - inode->i_blkbits);
const unsigned mask = blks_per_page - 1;
@@ -461,7 +461,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
mutex_unlock(&UFS_SB(sb)->s_lock);
ufs_change_blocknr(inode, fragment - oldcount, oldcount,
uspi->s_sbbase + tmp,
- uspi->s_sbbase + result, &locked_folio->page);
+ uspi->s_sbbase + result, locked_folio);
*err = 0;
write_seqlock(&UFS_I(inode)->meta_lock);
ufs_cpu_to_data_ptr(sb, p, result);
--
2.39.5
^ permalink raw reply related [flat|nested] 18+ messages in thread