Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
54e2264e
Commit
54e2264e
authored
6 years ago
by
Kent Overstreet
Committed by
Kent Overstreet
1 year ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcachefs: convert truncate to bch2_extent_update()
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
08af47df
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
93 additions
and
23 deletions
+93
-23
fs/bcachefs/fs-io.c
fs/bcachefs/fs-io.c
+93
-23
No files found.
fs/bcachefs/fs-io.c
View file @
54e2264e
...
@@ -2116,6 +2116,55 @@ int bch2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
...
@@ -2116,6 +2116,55 @@ int bch2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
/* truncate: */
/* truncate: */
static
int
__bch2_fpunch
(
struct
bch_fs
*
c
,
struct
bch_inode_info
*
inode
,
u64
start_offset
,
u64
end_offset
,
u64
*
journal_seq
)
{
struct
bpos
start
=
POS
(
inode
->
v
.
i_ino
,
start_offset
);
struct
bpos
end
=
POS
(
inode
->
v
.
i_ino
,
end_offset
);
unsigned
max_sectors
=
KEY_SIZE_MAX
&
(
~
0
<<
c
->
block_bits
);
struct
btree_trans
trans
;
struct
btree_iter
*
iter
;
struct
bkey_s_c
k
;
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_EXTENTS
,
start
,
BTREE_ITER_INTENT
);
while
((
k
=
bch2_btree_iter_peek
(
iter
)).
k
&&
!
(
ret
=
btree_iter_err
(
k
))
&&
bkey_cmp
(
iter
->
pos
,
end
)
<
0
)
{
struct
disk_reservation
disk_res
=
bch2_disk_reservation_init
(
c
,
0
);
struct
bkey_i
delete
;
bkey_init
(
&
delete
.
k
);
delete
.
k
.
p
=
iter
->
pos
;
/* create the biggest key we can */
bch2_key_resize
(
&
delete
.
k
,
max_sectors
);
bch2_cut_back
(
end
,
&
delete
.
k
);
ret
=
bch2_extent_update
(
&
trans
,
inode
,
&
disk_res
,
NULL
,
iter
,
&
delete
,
0
,
true
,
true
,
NULL
);
bch2_disk_reservation_put
(
c
,
&
disk_res
);
if
(
ret
==
-
EINTR
)
ret
=
0
;
if
(
ret
)
break
;
bch2_btree_iter_cond_resched
(
iter
);
}
bch2_trans_exit
(
&
trans
);
return
ret
;
}
static
inline
int
range_has_data
(
struct
bch_fs
*
c
,
static
inline
int
range_has_data
(
struct
bch_fs
*
c
,
struct
bpos
start
,
struct
bpos
start
,
struct
bpos
end
)
struct
bpos
end
)
...
@@ -2238,12 +2287,32 @@ static int bch2_extend(struct bch_inode_info *inode, struct iattr *iattr)
...
@@ -2238,12 +2287,32 @@ static int bch2_extend(struct bch_inode_info *inode, struct iattr *iattr)
return
ret
;
return
ret
;
}
}
static
int
bch2_truncate_finish_fn
(
struct
bch_inode_info
*
inode
,
struct
bch_inode_unpacked
*
bi
,
void
*
p
)
{
struct
bch_fs
*
c
=
inode
->
v
.
i_sb
->
s_fs_info
;
bi
->
bi_flags
&=
~
BCH_INODE_I_SIZE_DIRTY
;
bi
->
bi_mtime
=
bi
->
bi_ctime
=
bch2_current_time
(
c
);
return
0
;
}
static
int
bch2_truncate_start_fn
(
struct
bch_inode_info
*
inode
,
struct
bch_inode_unpacked
*
bi
,
void
*
p
)
{
u64
*
new_i_size
=
p
;
bi
->
bi_flags
|=
BCH_INODE_I_SIZE_DIRTY
;
bi
->
bi_size
=
*
new_i_size
;
return
0
;
}
int
bch2_truncate
(
struct
bch_inode_info
*
inode
,
struct
iattr
*
iattr
)
int
bch2_truncate
(
struct
bch_inode_info
*
inode
,
struct
iattr
*
iattr
)
{
{
struct
bch_fs
*
c
=
inode
->
v
.
i_sb
->
s_fs_info
;
struct
bch_fs
*
c
=
inode
->
v
.
i_sb
->
s_fs_info
;
struct
address_space
*
mapping
=
inode
->
v
.
i_mapping
;
struct
address_space
*
mapping
=
inode
->
v
.
i_mapping
;
struct
i_sectors_hook
i_sectors_hook
=
u64
new_i_size
=
iattr
->
ia_size
;
i_sectors_hook_init
(
inode
,
BCH_INODE_I_SIZE_DIRTY
);
bool
shrink
;
bool
shrink
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -2256,12 +2325,12 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
...
@@ -2256,12 +2325,12 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
if
(
!
shrink
)
{
if
(
!
shrink
)
{
ret
=
bch2_extend
(
inode
,
iattr
);
ret
=
bch2_extend
(
inode
,
iattr
);
goto
err
_put_pagecache
;
goto
err
;
}
}
ret
=
bch2_truncate_page
(
inode
,
iattr
->
ia_size
);
ret
=
bch2_truncate_page
(
inode
,
iattr
->
ia_size
);
if
(
unlikely
(
ret
))
if
(
unlikely
(
ret
))
goto
err
_put_pagecache
;
goto
err
;
if
(
iattr
->
ia_size
>
inode
->
ei_inode
.
bi_size
)
if
(
iattr
->
ia_size
>
inode
->
ei_inode
.
bi_size
)
ret
=
filemap_write_and_wait_range
(
mapping
,
ret
=
filemap_write_and_wait_range
(
mapping
,
...
@@ -2272,37 +2341,38 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
...
@@ -2272,37 +2341,38 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
round_down
(
iattr
->
ia_size
,
PAGE_SIZE
),
round_down
(
iattr
->
ia_size
,
PAGE_SIZE
),
iattr
->
ia_size
-
1
);
iattr
->
ia_size
-
1
);
if
(
ret
)
if
(
ret
)
goto
err
_put_pagecache
;
goto
err
;
i_sectors_hook
.
new_i_size
=
iattr
->
ia_size
;
mutex_lock
(
&
inode
->
ei_update_lock
);
ret
=
bch2_write_inode
(
c
,
inode
,
bch2_truncate_start_fn
,
&
new_i_size
,
0
);
mutex_unlock
(
&
inode
->
ei_update_lock
);
ret
=
i_sectors_dirty_start
(
c
,
&
i_sectors_hook
);
if
(
unlikely
(
ret
))
if
(
unlikely
(
ret
))
goto
err
_put_pagecache
;
goto
err
;
truncate_setsize
(
&
inode
->
v
,
iattr
->
ia_size
);
truncate_setsize
(
&
inode
->
v
,
iattr
->
ia_size
);
ret
=
bch2_inode_truncate
(
c
,
inode
->
v
.
i_ino
,
/*
round_up
(
iattr
->
ia_size
,
PAGE_SIZE
)
>>
9
,
* XXX: need a comment explaining why PAGE_SIZE and not block_bytes()
&
i_sectors_hook
.
hook
,
* here:
&
inode
->
ei_journal_seq
);
*/
ret
=
__bch2_fpunch
(
c
,
inode
,
round_up
(
iattr
->
ia_size
,
PAGE_SIZE
)
>>
9
,
U64_MAX
,
&
inode
->
ei_journal_seq
);
if
(
unlikely
(
ret
))
if
(
unlikely
(
ret
))
goto
err
_put_sectors_dirty
;
goto
err
;
/* ATTR_MODE will never be set here, ns argument isn't needed: */
/* ATTR_MODE will never be set here, ns argument isn't needed: */
setattr_copy
(
NULL
,
&
inode
->
v
,
iattr
);
setattr_copy
(
NULL
,
&
inode
->
v
,
iattr
);
out:
ret
=
i_sectors_dirty_finish
(
c
,
&
i_sectors_hook
)
?:
ret
;
mutex_lock
(
&
inode
->
ei_update_lock
);
err_put_pagecache:
ret
=
bch2_write_inode
(
c
,
inode
,
bch2_truncate_finish_fn
,
NULL
,
ATTR_MTIME
|
ATTR_CTIME
);
mutex_unlock
(
&
inode
->
ei_update_lock
);
err:
bch2_pagecache_block_put
(
&
inode
->
ei_pagecache_lock
);
bch2_pagecache_block_put
(
&
inode
->
ei_pagecache_lock
);
return
ret
;
return
ret
;
err_put_sectors_dirty:
/*
* On error - in particular, bch2_truncate_page() error - don't clear
* I_SIZE_DIRTY, as we've left data above i_size!:
*/
i_sectors_hook
.
flags
&=
~
BCH_INODE_I_SIZE_DIRTY
;
goto
out
;
}
}
/* fallocate: */
/* fallocate: */
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment