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
89fdbccc
Commit
89fdbccc
authored
Oct 15, 2004
by
Anton Altaparmakov
Browse files
Options
Browse Files
Download
Plain Diff
Merge
ssh://linux-ntfs@bkbits.net/ntfs-2.6-devel
into cantab.net:/home/src/ntfs-2.6-devel
parents
ada8d309
921372c2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
61 additions
and
48 deletions
+61
-48
fs/ntfs/ChangeLog
fs/ntfs/ChangeLog
+10
-0
fs/ntfs/aops.c
fs/ntfs/aops.c
+26
-25
fs/ntfs/aops.h
fs/ntfs/aops.h
+1
-2
fs/ntfs/index.h
fs/ntfs/index.h
+2
-2
fs/ntfs/inode.c
fs/ntfs/inode.c
+2
-2
fs/ntfs/mft.c
fs/ntfs/mft.c
+20
-17
No files found.
fs/ntfs/ChangeLog
View file @
89fdbccc
...
...
@@ -118,6 +118,16 @@ ToDo/Notes:
inode semaphore around the code thst sets ni->itype.index.bmp_ino to
NULL and reorganize the code to optimize it a bit. (Thanks to
Christoph Hellwig for spotting this.)
- Modify fs/ntfs/aops.c::mark_ntfs_record_dirty() to no longer take the
ntfs inode as a parameter as this is confusing and misleading and the
needed ntfs inode is available via NTFS_I(page->mapping->host).
Adapt all callers to this change.
- Modify fs/ntfs/mft.c::write_mft_record_nolock() and
fs/ntfs/aops.c::ntfs_write_mst_block() to only check the dirty state
of the first buffer in a record and to take this as the ntfs record
dirty state. We cannot look at the dirty state for subsequent
buffers because we might be racing with
fs/ntfs/aops.c::mark_ntfs_record_dirty().
2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
...
...
fs/ntfs/aops.c
View file @
89fdbccc
...
...
@@ -868,23 +868,24 @@ static int ntfs_write_mst_block(struct writeback_control *wbc,
clear_buffer_dirty
(
bh
);
continue
;
}
if
(
rec_block
==
block
)
{
if
(
likely
(
block
<
rec_block
))
{
/*
* This block is not the first one in the record. We
* ignore the buffer's dirty state because we could
* have raced with a parallel mark_ntfs_record_dirty().
*/
if
(
!
rec_is_dirty
)
continue
;
}
else
/* if (block == rec_block) */
{
BUG_ON
(
block
>
rec_block
);
/* This block is the first one in the record. */
rec_block
+=
bhs_per_rec
;
if
(
!
buffer_dirty
(
bh
))
{
/* Clean
buffer
s are not written out. */
/* Clean
record
s are not written out. */
rec_is_dirty
=
FALSE
;
continue
;
}
rec_is_dirty
=
TRUE
;
}
else
{
/* This block is not the first one in the record. */
if
(
!
buffer_dirty
(
bh
))
{
/* Clean buffers are not written out. */
BUG_ON
(
rec_is_dirty
);
continue
;
}
BUG_ON
(
!
rec_is_dirty
);
}
BUG_ON
(
!
buffer_mapped
(
bh
));
BUG_ON
(
!
buffer_uptodate
(
bh
));
...
...
@@ -973,10 +974,8 @@ static int ntfs_write_mst_block(struct writeback_control *wbc,
continue
;
if
(
unlikely
(
test_set_buffer_locked
(
tbh
)))
BUG
();
if
(
unlikely
(
!
test_clear_buffer_dirty
(
tbh
)))
{
unlock_buffer
(
tbh
);
continue
;
}
/* The buffer dirty state is now irrelevant, just clean it. */
clear_buffer_dirty
(
tbh
);
BUG_ON
(
!
buffer_uptodate
(
tbh
));
BUG_ON
(
!
buffer_mapped
(
tbh
));
get_bh
(
tbh
);
...
...
@@ -2132,9 +2131,8 @@ struct address_space_operations ntfs_mst_aops = {
/**
* mark_ntfs_record_dirty - mark an ntfs record dirty
* @ni: ntfs inode containing the ntfs record to be marked dirty
* @page: page containing the ntfs record to mark dirty
* @
rec_start
: byte offset within @page at which the ntfs record begins
* @
ofs
: byte offset within @page at which the ntfs record begins
*
* If the ntfs record is the same size as the page cache page @page, set all
* buffers in the page dirty. Otherwise, set only the buffers in which the
...
...
@@ -2143,26 +2141,29 @@ struct address_space_operations ntfs_mst_aops = {
* Also, set the page containing the ntfs record dirty, which also marks the
* vfs inode the ntfs record belongs to dirty (I_DIRTY_PAGES).
*/
void
mark_ntfs_record_dirty
(
ntfs_inode
*
ni
,
struct
page
*
page
,
unsigned
int
rec_start
)
{
void
mark_ntfs_record_dirty
(
struct
page
*
page
,
const
unsigned
int
ofs
)
{
ntfs_inode
*
ni
;
struct
buffer_head
*
bh
,
*
head
;
unsigned
int
rec_end
,
bh_size
,
bh_start
,
bh_end
;
unsigned
int
end
,
bh_size
,
bh_ofs
;
BUG_ON
(
!
page
);
BUG_ON
(
!
page_has_buffers
(
page
));
ni
=
NTFS_I
(
page
->
mapping
->
host
);
BUG_ON
(
!
ni
);
if
(
ni
->
itype
.
index
.
block_size
==
PAGE_CACHE_SIZE
)
{
__set_page_dirty_buffers
(
page
);
return
;
}
rec_end
=
rec_start
+
ni
->
itype
.
index
.
block_size
;
end
=
ofs
+
ni
->
itype
.
index
.
block_size
;
bh_size
=
ni
->
vol
->
sb
->
s_blocksize
;
bh_start
=
0
;
bh
=
head
=
page_buffers
(
page
);
do
{
bh_end
=
bh_start
+
bh_size
;
if
((
bh_start
>=
rec_start
)
&&
(
bh_end
<=
rec_end
))
set_buffer_dirty
(
bh
);
bh_start
=
bh_end
;
bh_ofs
=
bh_offset
(
bh
);
if
(
bh_ofs
+
bh_size
<=
ofs
)
continue
;
if
(
unlikely
(
bh_ofs
>=
end
))
break
;
set_buffer_dirty
(
bh
);
}
while
((
bh
=
bh
->
b_this_page
)
!=
head
);
__set_page_dirty_nobuffers
(
page
);
}
...
...
fs/ntfs/aops.h
View file @
89fdbccc
...
...
@@ -95,8 +95,7 @@ static inline struct page *ntfs_map_page(struct address_space *mapping,
#ifdef NTFS_RW
extern
void
mark_ntfs_record_dirty
(
ntfs_inode
*
ni
,
struct
page
*
page
,
unsigned
int
rec_start
);
extern
void
mark_ntfs_record_dirty
(
struct
page
*
page
,
const
unsigned
int
ofs
);
#endif
/* NTFS_RW */
...
...
fs/ntfs/index.h
View file @
89fdbccc
...
...
@@ -139,8 +139,8 @@ static inline void ntfs_index_entry_mark_dirty(ntfs_index_context *ictx)
if
(
ictx
->
is_in_root
)
mark_mft_record_dirty
(
ictx
->
actx
->
ntfs_ino
);
else
mark_ntfs_record_dirty
(
ictx
->
idx_ni
,
ictx
->
page
,
(
u8
*
)
ictx
->
ia
-
(
u8
*
)
page_address
(
ictx
->
page
));
mark_ntfs_record_dirty
(
ictx
->
page
,
(
u8
*
)
ictx
->
ia
-
(
u8
*
)
page_address
(
ictx
->
page
));
}
#endif
/* NTFS_RW */
...
...
fs/ntfs/inode.c
View file @
89fdbccc
...
...
@@ -2513,8 +2513,8 @@ int ntfs_write_inode(struct inode *vi, int sync)
* this function returns.
*/
if
(
modified
&&
!
NInoTestSetDirty
(
ctx
->
ntfs_ino
))
mark_ntfs_record_dirty
(
NTFS_I
(
ni
->
vol
->
mft_ino
)
,
ctx
->
ntfs_ino
->
page
,
ctx
->
ntfs_ino
->
page
_ofs
);
mark_ntfs_record_dirty
(
ctx
->
ntfs_ino
->
page
,
ctx
->
ntfs_ino
->
page_ofs
);
ntfs_attr_put_search_ctx
(
ctx
);
/* Now the access times are updated, write the base mft record. */
if
(
NInoDirty
(
ni
))
...
...
fs/ntfs/mft.c
View file @
89fdbccc
...
...
@@ -380,8 +380,7 @@ void __mark_mft_record_dirty(ntfs_inode *ni)
ntfs_debug
(
"Entering for inode 0x%lx."
,
ni
->
mft_no
);
BUG_ON
(
NInoAttr
(
ni
));
mark_ntfs_record_dirty
(
NTFS_I
(
ni
->
vol
->
mft_ino
),
ni
->
page
,
ni
->
page_ofs
);
mark_ntfs_record_dirty
(
ni
->
page
,
ni
->
page_ofs
);
/* Determine the base vfs inode and mark it dirty, too. */
down
(
&
ni
->
extent_lock
);
if
(
likely
(
ni
->
nr_extents
>=
0
))
...
...
@@ -573,8 +572,10 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
* ntfs inode @ni to backing store. If the mft record @m has a counterpart in
* the mft mirror, that is also updated.
*
* We only write the mft record if the ntfs inode @ni is dirty and the buffers
* belonging to its mft record are dirty, too.
* We only write the mft record if the ntfs inode @ni is dirty and the first
* buffer belonging to its mft record is dirty, too. We ignore the dirty state
* of subsequent buffers because we could have raced with
* fs/ntfs/aops.c::mark_ntfs_record_dirty().
*
* On success, clean the mft record and return 0. On error, leave the mft
* record dirty and return -errno. The caller should call make_bad_inode() on
...
...
@@ -633,21 +634,23 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
continue
;
if
(
unlikely
(
block_start
>=
m_end
))
break
;
/*
* If the buffer is clean and it is the first buffer of the mft
* record, it was written out by other means already so we are
* done. For safety we make sure all the other buffers are
* clean also. If it is clean but not the first buffer and the
* first buffer was dirty it is a bug.
*/
if
(
!
buffer_dirty
(
bh
))
{
if
(
block_start
==
m_start
)
if
(
block_start
==
m_start
)
{
/* This block is the first one in the record. */
if
(
!
buffer_dirty
(
bh
))
{
/* Clean records are not written out. */
rec_is_dirty
=
FALSE
;
else
BUG_ON
(
rec_is_dirty
);
continue
;
continue
;
}
rec_is_dirty
=
TRUE
;
}
else
{
/*
* This block is not the first one in the record. We
* ignore the buffer's dirty state because we could
* have raced with a parallel mark_ntfs_record_dirty().
*/
if
(
!
rec_is_dirty
)
continue
;
}
BUG_ON
(
!
rec_is_dirty
);
BUG_ON
(
!
buffer_mapped
(
bh
));
BUG_ON
(
!
buffer_uptodate
(
bh
));
BUG_ON
(
!
nr_bhs
&&
(
m_start
!=
block_start
));
...
...
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