Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
29578dbe
Commit
29578dbe
authored
Sep 15, 2009
by
Stephen Rothwell
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'ubifs/linux-next'
Conflicts: fs/ubifs/super.c
parents
7c30c494
873a64c7
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
176 additions
and
120 deletions
+176
-120
fs/ubifs/commit.c
fs/ubifs/commit.c
+1
-1
fs/ubifs/debug.c
fs/ubifs/debug.c
+1
-1
fs/ubifs/debug.h
fs/ubifs/debug.h
+3
-0
fs/ubifs/file.c
fs/ubifs/file.c
+30
-32
fs/ubifs/gc.c
fs/ubifs/gc.c
+1
-1
fs/ubifs/key.h
fs/ubifs/key.h
+6
-29
fs/ubifs/log.c
fs/ubifs/log.c
+1
-1
fs/ubifs/lprops.c
fs/ubifs/lprops.c
+1
-1
fs/ubifs/master.c
fs/ubifs/master.c
+14
-6
fs/ubifs/orphan.c
fs/ubifs/orphan.c
+4
-3
fs/ubifs/recovery.c
fs/ubifs/recovery.c
+2
-2
fs/ubifs/replay.c
fs/ubifs/replay.c
+3
-3
fs/ubifs/scan.c
fs/ubifs/scan.c
+22
-10
fs/ubifs/super.c
fs/ubifs/super.c
+10
-23
fs/ubifs/tnc.c
fs/ubifs/tnc.c
+73
-3
fs/ubifs/tnc_commit.c
fs/ubifs/tnc_commit.c
+1
-1
fs/ubifs/ubifs.h
fs/ubifs/ubifs.h
+1
-1
fs/ubifs/xattr.c
fs/ubifs/xattr.c
+2
-2
No files found.
fs/ubifs/commit.c
View file @
29578dbe
...
...
@@ -510,7 +510,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
int
lnum
,
offs
,
len
,
err
=
0
,
uninitialized_var
(
last_level
),
child_cnt
;
int
first
=
1
,
iip
;
struct
ubifs_debug_info
*
d
=
c
->
dbg
;
union
ubifs_key
lower_key
,
upper_key
,
l_key
,
u_key
;
union
ubifs_key
uninitialized_var
(
lower_key
)
,
upper_key
,
l_key
,
u_key
;
unsigned
long
long
uninitialized_var
(
last_sqnum
);
struct
ubifs_idx_node
*
idx
;
struct
list_head
list
;
...
...
fs/ubifs/debug.c
View file @
29578dbe
...
...
@@ -724,7 +724,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
printk
(
KERN_DEBUG
"(pid %d) start dumping LEB %d
\n
"
,
current
->
pid
,
lnum
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
,
0
);
if
(
IS_ERR
(
sleb
))
{
ubifs_err
(
"scan error %d"
,
(
int
)
PTR_ERR
(
sleb
));
return
;
...
...
fs/ubifs/debug.h
View file @
29578dbe
...
...
@@ -321,6 +321,8 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
int
dbg_check_lprops
(
struct
ubifs_info
*
c
);
int
dbg_check_lpt_nodes
(
struct
ubifs_info
*
c
,
struct
ubifs_cnode
*
cnode
,
int
row
,
int
col
);
int
dbg_check_inode_size
(
struct
ubifs_info
*
c
,
const
struct
inode
*
inode
,
loff_t
size
);
/* Force the use of in-the-gaps method for testing */
...
...
@@ -460,6 +462,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
#define dbg_check_heap(c, heap, cat, add_pos) ({})
#define dbg_check_lprops(c) 0
#define dbg_check_lpt_nodes(c, cnode, row, col) 0
#define dbg_check_inode_size(c, inode, size) 0
#define dbg_force_in_the_gaps_enabled 0
#define dbg_force_in_the_gaps() 0
#define dbg_failure_mode 0
...
...
fs/ubifs/file.c
View file @
29578dbe
...
...
@@ -21,34 +21,32 @@
*/
/*
* This file implements VFS file and inode operations
of
regular files, device
* This file implements VFS file and inode operations
for
regular files, device
* nodes and symlinks as well as address space operations.
*
* UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the
* page is dirty and is used for budgeting purposes - dirty pages should not be
* budgeted. The PG_checked flag is set if full budgeting is required for the
* page e.g., when it corresponds to a file hole or it is just beyond the file
* size. The budgeting is done in 'ubifs_write_begin()', because it is OK to
* fail in this function, and the budget is released in 'ubifs_write_end()'. So
* the PG_private and PG_checked flags carry the information about how the page
* was budgeted, to make it possible to release the budget properly.
* UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if
* the page is dirty and is used for optimization purposes - dirty pages are
* not budgeted so the flag shows that 'ubifs_write_end()' should not release
* the budget for this page. The @PG_checked flag is set if full budgeting is
* required for the page e.g., when it corresponds to a file hole or it is
* beyond the file size. The budgeting is done in 'ubifs_write_begin()', because
* it is OK to fail in this function, and the budget is released in
* 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry
* information about how the page was budgeted, to make it possible to release
* the budget properly.
*
* A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations
* we implement. However, this is not true for '->writepage()', which might be
* called with 'i_mutex' unlocked. For example, when pdflush is performing
* write-back, it calls 'writepage()' with unlocked 'i_mutex', although the
* inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is
* locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim
* path'. So, in '->writepage()' we are only guaranteed that the page is
* locked.
* A thing to keep in mind: inode @i_mutex is locked in most VFS operations we
* implement. However, this is not true for 'ubifs_writepage()', which may be
* called with @i_mutex unlocked. For example, when pdflush is doing background
* write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal"
* work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the
* "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()'
* we are only guaranteed that the page is locked.
*
* Similarly, 'i_mutex' does not have to be locked in readpage(), e.g.,
* readahead path does not have it locked ("sys_read -> generic_file_aio_read
* -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is
* not set as well. However, UBIFS disables readahead.
*
* This, for example means that there might be 2 concurrent '->writepage()'
* calls for the same inode, but different inode dirty pages.
* Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the
* read-ahead path does not lock it ("sys_read -> generic_file_aio_read ->
* ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not
* set as well. However, UBIFS disables readahead.
*/
#include "ubifs.h"
...
...
@@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
/*
* We change whole page so no need to load it. But we
* have to set the @PG_checked flag to make the further
* code
the page is new. This might be not true, but i
t
*
is better to budget more that to read the page from
* the media.
* code
know that the page is new. This might be no
t
*
true, but it is better to budget more than to read
* the
page from the
media.
*/
SetPageChecked
(
page
);
skipped_read
=
1
;
...
...
@@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
}
/*
* Whee, we aquired budgeting quickly - without involving
* garbage-collection, committing or forc
e
ing write-back. We return
* Whee, we a
c
quired budgeting quickly - without involving
* garbage-collection, committing or forcing write-back. We return
* with @ui->ui_mutex locked if we are appending pages, and unlocked
* otherwise. This is an optimization (slightly hacky though).
*/
...
...
@@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
/*
* Return 0 to force VFS to repeat the whole operation, or the
* error code if 'do_readpage()' fail
e
s.
* error code if 'do_readpage()' fails.
*/
copied
=
do_readpage
(
page
);
goto
out
;
...
...
@@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
ui
->
ui_size
=
inode
->
i_size
;
/* Truncation changes inode [mc]time */
inode
->
i_mtime
=
inode
->
i_ctime
=
ubifs_current_time
(
inode
);
/*
The o
ther attributes may be changed at the same time as well */
/*
O
ther attributes may be changed at the same time as well */
do_attr_changes
(
inode
,
attr
);
err
=
ubifs_jnl_truncate
(
c
,
inode
,
old_size
,
new_size
);
mutex_unlock
(
&
ui
->
ui_mutex
);
out_budg:
if
(
budgeted
)
ubifs_release_budget
(
c
,
&
req
);
...
...
fs/ubifs/gc.c
View file @
29578dbe
...
...
@@ -529,7 +529,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
* We scan the entire LEB even though we only really need to scan up to
* (c->leb_size - lp->free).
*/
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
,
0
);
if
(
IS_ERR
(
sleb
))
return
PTR_ERR
(
sleb
);
...
...
fs/ubifs/key.h
View file @
29578dbe
...
...
@@ -228,23 +228,6 @@ static inline void xent_key_init(const struct ubifs_info *c,
key
->
u32
[
1
]
=
hash
|
(
UBIFS_XENT_KEY
<<
UBIFS_S_KEY_HASH_BITS
);
}
/**
* xent_key_init_hash - initialize extended attribute entry key without
* re-calculating hash function.
* @c: UBIFS file-system description object
* @key: key to initialize
* @inum: host inode number
* @hash: extended attribute entry name hash
*/
static
inline
void
xent_key_init_hash
(
const
struct
ubifs_info
*
c
,
union
ubifs_key
*
key
,
ino_t
inum
,
uint32_t
hash
)
{
ubifs_assert
(
!
(
hash
&
~
UBIFS_S_KEY_HASH_MASK
));
key
->
u32
[
0
]
=
inum
;
key
->
u32
[
1
]
=
hash
|
(
UBIFS_XENT_KEY
<<
UBIFS_S_KEY_HASH_BITS
);
}
/**
* xent_key_init_flash - initialize on-flash extended attribute entry key.
* @c: UBIFS file-system description object
...
...
@@ -295,22 +278,15 @@ static inline void data_key_init(const struct ubifs_info *c,
}
/**
*
data_key_init_flash - initialize on-flash data key
.
*
highest_data_key - get the highest possible data key for an inode
.
* @c: UBIFS file-system description object
* @k: key to initialize
* @k
ey
: key to initialize
* @inum: inode number
* @block: block number
*/
static
inline
void
data_key_init_flash
(
const
struct
ubifs_info
*
c
,
void
*
k
,
ino_t
inum
,
unsigned
int
block
)
static
inline
void
highest_data_key
(
const
struct
ubifs_info
*
c
,
union
ubifs_key
*
key
,
ino_t
inum
)
{
union
ubifs_key
*
key
=
k
;
ubifs_assert
(
!
(
block
&
~
UBIFS_S_KEY_BLOCK_MASK
));
key
->
j32
[
0
]
=
cpu_to_le32
(
inum
);
key
->
j32
[
1
]
=
cpu_to_le32
(
block
|
(
UBIFS_DATA_KEY
<<
UBIFS_S_KEY_BLOCK_BITS
));
memset
(
k
+
8
,
0
,
UBIFS_MAX_KEY_LEN
-
8
);
data_key_init
(
c
,
key
,
inum
,
UBIFS_S_KEY_BLOCK_MASK
);
}
/**
...
...
@@ -554,4 +530,5 @@ static inline unsigned long long key_max_inode_size(const struct ubifs_info *c)
return
0
;
}
}
#endif
/* !__UBIFS_KEY_H__ */
fs/ubifs/log.c
View file @
29578dbe
...
...
@@ -695,7 +695,7 @@ int ubifs_consolidate_log(struct ubifs_info *c)
lnum
=
c
->
ltail_lnum
;
write_lnum
=
lnum
;
while
(
1
)
{
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
,
0
);
if
(
IS_ERR
(
sleb
))
{
err
=
PTR_ERR
(
sleb
);
goto
out_free
;
...
...
fs/ubifs/lprops.c
View file @
29578dbe
...
...
@@ -1096,7 +1096,7 @@ static int scan_check_cb(struct ubifs_info *c,
}
}
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
,
0
);
if
(
IS_ERR
(
sleb
))
{
/*
* After an unclean unmount, empty and freeable LEBs
...
...
fs/ubifs/master.c
View file @
29578dbe
...
...
@@ -29,7 +29,8 @@
* @c: UBIFS file-system description object
*
* This function scans the master node LEBs and search for the latest master
* node. Returns zero in case of success and a negative error code in case of
* node. Returns zero in case of success, %-EUCLEAN if there master area is
* corrupted and requires recovery, and a negative error code in case of
* failure.
*/
static
int
scan_for_master
(
struct
ubifs_info
*
c
)
...
...
@@ -40,7 +41,7 @@ static int scan_for_master(struct ubifs_info *c)
lnum
=
UBIFS_MST_LNUM
;
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
,
1
);
if
(
IS_ERR
(
sleb
))
return
PTR_ERR
(
sleb
);
nodes_cnt
=
sleb
->
nodes_cnt
;
...
...
@@ -48,7 +49,7 @@ static int scan_for_master(struct ubifs_info *c)
snod
=
list_entry
(
sleb
->
nodes
.
prev
,
struct
ubifs_scan_node
,
list
);
if
(
snod
->
type
!=
UBIFS_MST_NODE
)
goto
out
;
goto
out
_dump
;
memcpy
(
c
->
mst_node
,
snod
->
node
,
snod
->
len
);
offs
=
snod
->
offs
;
}
...
...
@@ -56,7 +57,7 @@ static int scan_for_master(struct ubifs_info *c)
lnum
+=
1
;
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
,
1
);
if
(
IS_ERR
(
sleb
))
return
PTR_ERR
(
sleb
);
if
(
sleb
->
nodes_cnt
!=
nodes_cnt
)
...
...
@@ -65,7 +66,7 @@ static int scan_for_master(struct ubifs_info *c)
goto
out
;
snod
=
list_entry
(
sleb
->
nodes
.
prev
,
struct
ubifs_scan_node
,
list
);
if
(
snod
->
type
!=
UBIFS_MST_NODE
)
goto
out
;
goto
out
_dump
;
if
(
snod
->
offs
!=
offs
)
goto
out
;
if
(
memcmp
((
void
*
)
c
->
mst_node
+
UBIFS_CH_SZ
,
...
...
@@ -78,6 +79,12 @@ static int scan_for_master(struct ubifs_info *c)
out:
ubifs_scan_destroy
(
sleb
);
return
-
EUCLEAN
;
out_dump:
ubifs_err
(
"unexpected node type %d master LEB %d:%d"
,
snod
->
type
,
lnum
,
snod
->
offs
);
ubifs_scan_destroy
(
sleb
);
return
-
EINVAL
;
}
...
...
@@ -256,7 +263,8 @@ int ubifs_read_master(struct ubifs_info *c)
err
=
scan_for_master
(
c
);
if
(
err
)
{
err
=
ubifs_recover_master_node
(
c
);
if
(
err
==
-
EUCLEAN
)
err
=
ubifs_recover_master_node
(
c
);
if
(
err
)
/*
* Note, we do not free 'c->mst_node' here because the
...
...
fs/ubifs/orphan.c
View file @
29578dbe
...
...
@@ -670,9 +670,10 @@ static int kill_orphans(struct ubifs_info *c)
struct
ubifs_scan_leb
*
sleb
;
dbg_rcvry
(
"LEB %d"
,
lnum
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
sbuf
,
1
);
if
(
IS_ERR
(
sleb
))
{
sleb
=
ubifs_recover_leb
(
c
,
lnum
,
0
,
c
->
sbuf
,
0
);
if
(
PTR_ERR
(
sleb
)
==
-
EUCLEAN
)
sleb
=
ubifs_recover_leb
(
c
,
lnum
,
0
,
c
->
sbuf
,
0
);
if
(
IS_ERR
(
sleb
))
{
err
=
PTR_ERR
(
sleb
);
break
;
...
...
@@ -899,7 +900,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
for
(
lnum
=
c
->
orph_first
;
lnum
<=
c
->
orph_last
;
lnum
++
)
{
struct
ubifs_scan_leb
*
sleb
;
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
dbg
->
buf
,
0
);
if
(
IS_ERR
(
sleb
))
{
err
=
PTR_ERR
(
sleb
);
break
;
...
...
fs/ubifs/recovery.c
View file @
29578dbe
...
...
@@ -286,7 +286,7 @@ int ubifs_recover_master_node(struct ubifs_info *c)
mst
=
mst2
;
}
dbg_rcvry
(
"recovered master node from LEB %d"
,
ubifs_msg
(
"recovered master node from LEB %d"
,
(
mst
==
mst1
?
UBIFS_MST_LNUM
:
UBIFS_MST_LNUM
+
1
));
memcpy
(
c
->
mst_node
,
mst
,
UBIFS_MST_NODE_SZ
);
...
...
@@ -790,7 +790,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
* We can only recover at the end of the log, so check that the
* next log LEB is empty or out of date.
*/
sleb
=
ubifs_scan
(
c
,
next_lnum
,
0
,
sbuf
);
sleb
=
ubifs_scan
(
c
,
next_lnum
,
0
,
sbuf
,
0
);
if
(
IS_ERR
(
sleb
))
return
sleb
;
if
(
sleb
->
nodes_cnt
)
{
...
...
fs/ubifs/replay.c
View file @
29578dbe
...
...
@@ -506,7 +506,7 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead,
if
(
c
->
need_recovery
)
sleb
=
ubifs_recover_leb
(
c
,
lnum
,
offs
,
c
->
sbuf
,
jhead
!=
GCHD
);
else
sleb
=
ubifs_scan
(
c
,
lnum
,
offs
,
c
->
sbuf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
offs
,
c
->
sbuf
,
0
);
if
(
IS_ERR
(
sleb
))
return
PTR_ERR
(
sleb
);
...
...
@@ -836,8 +836,8 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
const
struct
ubifs_cs_node
*
node
;
dbg_mnt
(
"replay log LEB %d:%d"
,
lnum
,
offs
);
sleb
=
ubifs_scan
(
c
,
lnum
,
offs
,
sbuf
);
if
(
IS_ERR
(
sleb
)
)
{
sleb
=
ubifs_scan
(
c
,
lnum
,
offs
,
sbuf
,
c
->
need_recovery
);
if
(
IS_ERR
(
sleb
))
{
if
(
PTR_ERR
(
sleb
)
!=
-
EUCLEAN
||
!
c
->
need_recovery
)
return
PTR_ERR
(
sleb
);
sleb
=
ubifs_recover_log_leb
(
c
,
lnum
,
offs
,
sbuf
);
...
...
fs/ubifs/scan.c
View file @
29578dbe
...
...
@@ -108,10 +108,9 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
/* Make the node pads to 8-byte boundary */
if
((
node_len
+
pad_len
)
&
7
)
{
if
(
!
quiet
)
{
if
(
!
quiet
)
dbg_err
(
"bad padding length %d - %d"
,
offs
,
offs
+
node_len
+
pad_len
);
}
return
SCANNED_A_BAD_PAD_NODE
;
}
...
...
@@ -253,15 +252,19 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
* @c: UBIFS file-system description object
* @lnum: logical eraseblock number
* @offs: offset to start at (usually zero)
* @sbuf: scan buffer (must be c->leb_size)
* @sbuf: scan buffer (must be of @c->leb_size bytes in size)
* @quiet: print no messages
*
* This function scans LEB number @lnum and returns complete information about
* its contents. Returns the scaned information in case of success and,
* %-EUCLEAN if the LEB neads recovery, and other negative error codes in case
* of failure.
*
* If @quiet is non-zero, this function does not print large and scary
* error messages and flash dumps in case of errors.
*/
struct
ubifs_scan_leb
*
ubifs_scan
(
const
struct
ubifs_info
*
c
,
int
lnum
,
int
offs
,
void
*
sbuf
)
int
offs
,
void
*
sbuf
,
int
quiet
)
{
void
*
buf
=
sbuf
+
offs
;
int
err
,
len
=
c
->
leb_size
-
offs
;
...
...
@@ -280,7 +283,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
cond_resched
();
ret
=
ubifs_scan_a_node
(
c
,
buf
,
len
,
lnum
,
offs
,
0
);
ret
=
ubifs_scan_a_node
(
c
,
buf
,
len
,
lnum
,
offs
,
quiet
);
if
(
ret
>
0
)
{
/* Padding bytes or a valid padding node */
offs
+=
ret
;
...
...
@@ -320,7 +323,9 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
}
if
(
offs
%
c
->
min_io_size
)
{
ubifs_err
(
"empty space starts at non-aligned offset %d"
,
offs
);
if
(
!
quiet
)
ubifs_err
(
"empty space starts at non-aligned offset %d"
,
offs
);
goto
corrupted
;;
}
...
...
@@ -331,18 +336,25 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
break
;
for
(;
len
;
offs
++
,
buf
++
,
len
--
)
if
(
*
(
uint8_t
*
)
buf
!=
0xff
)
{
ubifs_err
(
"corrupt empty space at LEB %d:%d"
,
lnum
,
offs
);
if
(
!
quiet
)
ubifs_err
(
"corrupt empty space at LEB %d:%d"
,
lnum
,
offs
);
goto
corrupted
;
}
return
sleb
;
corrupted:
ubifs_scanned_corruption
(
c
,
lnum
,
offs
,
buf
);
if
(
!
quiet
)
{
ubifs_scanned_corruption
(
c
,
lnum
,
offs
,
buf
);
ubifs_err
(
"LEB %d scanning failed"
,
lnum
);
}
err
=
-
EUCLEAN
;
ubifs_scan_destroy
(
sleb
);
return
ERR_PTR
(
err
);
error:
ubifs_err
(
"LEB %d scanning failed
"
,
lnum
);
ubifs_err
(
"LEB %d scanning failed
, error %d"
,
lnum
,
err
);
ubifs_scan_destroy
(
sleb
);
return
ERR_PTR
(
err
);
}
...
...
fs/ubifs/super.c
View file @
29578dbe
...
...
@@ -36,7 +36,6 @@
#include <linux/mount.h>
#include <linux/math64.h>
#include <linux/writeback.h>
#include <linux/smp_lock.h>
#include "ubifs.h"
/*
...
...
@@ -318,6 +317,8 @@ static int ubifs_write_inode(struct inode *inode, int wait)
if
(
err
)
ubifs_err
(
"can't write inode %lu, error %d"
,
inode
->
i_ino
,
err
);
else
err
=
dbg_check_inode_size
(
c
,
inode
,
ui
->
ui_size
);
}
ui
->
dirty
=
0
;
...
...
@@ -447,17 +448,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
if
(
!
wait
)
return
0
;
/*
* VFS calls '->sync_fs()' before synchronizing all dirty inodes and
* pages, so synchronize them first, then commit the journal. Strictly
* speaking, it is not necessary to commit the journal here,
* synchronizing write-buffers would be enough. But committing makes
* UBIFS free space predictions much more accurate, so we want to let
* the user be able to get more accurate results of 'statfs()' after
* they synchronize the file system.
*/
sync_inodes_sb
(
sb
);
/*
* Synchronize write buffers, because 'ubifs_run_commit()' does not
* do this if it waits for an already running commit.
...
...
@@ -468,6 +458,13 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
return
err
;
}
/*
* Strictly speaking, it is not necessary to commit the journal here,
* synchronizing write-buffers would be enough. But committing makes
* UBIFS free space predictions much more accurate, so we want to let
* the user be able to get more accurate results of 'statfs()' after
* they synchronize the file system.
*/
err
=
ubifs_run_commit
(
c
);
if
(
err
)
return
err
;
...
...
@@ -1720,8 +1717,6 @@ static void ubifs_put_super(struct super_block *sb)
ubifs_msg
(
"un-mount UBI device %d, volume %d"
,
c
->
vi
.
ubi_num
,
c
->
vi
.
vol_id
);
lock_kernel
();
/*
* The following asserts are only valid if there has not been a failure
* of the media. For example, there will be dirty inodes if we failed
...
...
@@ -1786,8 +1781,6 @@ static void ubifs_put_super(struct super_block *sb)
ubi_close_volume
(
c
->
ubi
);
mutex_unlock
(
&
c
->
umount_mutex
);
kfree
(
c
);
unlock_kernel
();
}
static
int
ubifs_remount_fs
(
struct
super_block
*
sb
,
int
*
flags
,
char
*
data
)
...
...
@@ -1803,22 +1796,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
return
err
;
}
lock_kernel
();
if
((
sb
->
s_flags
&
MS_RDONLY
)
&&
!
(
*
flags
&
MS_RDONLY
))
{
if
(
c
->
ro_media
)
{
ubifs_msg
(
"cannot re-mount due to prior errors"
);
unlock_kernel
();
return
-
EROFS
;
}
err
=
ubifs_remount_rw
(
c
);
if
(
err
)
{
unlock_kernel
();
if
(
err
)
return
err
;
}
}
else
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
)
&&
(
*
flags
&
MS_RDONLY
))
{
if
(
c
->
ro_media
)
{
ubifs_msg
(
"cannot re-mount due to prior errors"
);
unlock_kernel
();
return
-
EROFS
;
}
ubifs_remount_ro
(
c
);
...
...
@@ -1833,7 +1821,6 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
}
ubifs_assert
(
c
->
lst
.
taken_empty_lebs
>
0
);
unlock_kernel
();
return
0
;
}
...
...
fs/ubifs/tnc.c
View file @
29578dbe
...
...
@@ -1159,8 +1159,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
* o exact match, i.e. the found zero-level znode contains key @key, then %1
* is returned and slot number of the matched branch is stored in @n;
* o not exact match, which means that zero-level znode does not contain
* @key, then %0 is returned and slot number of the close
d
branch is stored
* in
@n;
* @key, then %0 is returned and slot number of the close
st
branch is stored
* in @n;
* o @key is so small that it is even less than the lowest key of the
* leftmost zero-level node, then %0 is returned and %0 is stored in @n.
*
...
...
@@ -1433,7 +1433,7 @@ static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1)
* @lnum: LEB number is returned here
* @offs: offset is returned here
*
* This function look up and reads node with key @key. The caller has to make
* This function look
s
up and reads node with key @key. The caller has to make
* sure the @node buffer is large enough to fit the node. Returns zero in case
* of success, %-ENOENT if the node was not found, and a negative error code in
* case of failure. The node location can be returned in @lnum and @offs.
...
...
@@ -3268,3 +3268,73 @@ out_unlock:
mutex_unlock
(
&
c
->
tnc_mutex
);
return
err
;
}
#ifdef CONFIG_UBIFS_FS_DEBUG
/**
* dbg_check_inode_size - check if inode size is correct.
* @c: UBIFS file-system description object
* @inum: inode number
* @size: inode size
*
* This function makes sure that the inode size (@size) is correct and it does
* not have any pages beyond @size. Returns zero if the inode is OK, %-EINVAL
* if it has a data page beyond @size, and other negative error code in case of
* other errors.
*/
int
dbg_check_inode_size
(
struct
ubifs_info
*
c
,
const
struct
inode
*
inode
,
loff_t
size
)
{
int
err
,
n
;
union
ubifs_key
from_key
,
to_key
,
*
key
;
struct
ubifs_znode
*
znode
;
unsigned
int
block
;
if
(
!
S_ISREG
(
inode
->
i_mode
))
return
0
;
if
(
!
(
ubifs_chk_flags
&
UBIFS_CHK_GEN
))
return
0
;
block
=
(
size
+
UBIFS_BLOCK_SIZE
-
1
)
>>
UBIFS_BLOCK_SHIFT
;
data_key_init
(
c
,
&
from_key
,
inode
->
i_ino
,
block
);
highest_data_key
(
c
,
&
to_key
,
inode
->
i_ino
);
mutex_lock
(
&
c
->
tnc_mutex
);
err
=
ubifs_lookup_level0
(
c
,
&
from_key
,
&
znode
,
&
n
);
if
(
err
<
0
)
goto
out_unlock
;
if
(
err
)
{
err
=
-
EINVAL
;
key
=
&
from_key
;
goto
out_dump
;
}
err
=
tnc_next
(
c
,
&
znode
,
&
n
);
if
(
err
==
-
ENOENT
)
{
err
=
0
;
goto
out_unlock
;
}
if
(
err
<
0
)
goto
out_unlock
;
ubifs_assert
(
err
==
0
);
key
=
&
znode
->
zbranch
[
n
].
key
;
if
(
!
key_in_range
(
c
,
key
,
&
from_key
,
&
to_key
))
goto
out_unlock
;
out_dump:
block
=
key_block
(
c
,
key
);
ubifs_err
(
"inode %lu has size %lld, but there are data at offset %lld "
"(data key %s)"
,
(
unsigned
long
)
inode
->
i_ino
,
size
,
((
loff_t
)
block
)
<<
UBIFS_BLOCK_SHIFT
,
DBGKEY
(
key
));
dbg_dump_inode
(
c
,
inode
);
dbg_dump_stack
();
err
=
-
EINVAL
;
out_unlock:
mutex_unlock
(
&
c
->
tnc_mutex
);
return
err
;
}
#endif
/* CONFIG_UBIFS_FS_DEBUG */
fs/ubifs/tnc_commit.c
View file @
29578dbe
...
...
@@ -245,7 +245,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p)
* it is more comprehensive and less efficient than is needed for this
* purpose.
*/
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
ileb_buf
);
sleb
=
ubifs_scan
(
c
,
lnum
,
0
,
c
->
ileb_buf
,
0
);
c
->
ileb_len
=
0
;
if
(
IS_ERR
(
sleb
))
return
PTR_ERR
(
sleb
);
...
...
fs/ubifs/ubifs.h
View file @
29578dbe
...
...
@@ -1451,7 +1451,7 @@ int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode);
/* scan.c */
struct
ubifs_scan_leb
*
ubifs_scan
(
const
struct
ubifs_info
*
c
,
int
lnum
,
int
offs
,
void
*
sbuf
);
int
offs
,
void
*
sbuf
,
int
quiet
);
void
ubifs_scan_destroy
(
struct
ubifs_scan_leb
*
sleb
);
int
ubifs_scan_a_node
(
const
struct
ubifs_info
*
c
,
void
*
buf
,
int
len
,
int
lnum
,
int
offs
,
int
quiet
);
...
...
fs/ubifs/xattr.c
View file @
29578dbe
...
...
@@ -78,9 +78,9 @@ enum {
SECURITY_XATTR
,
};
static
struct
inode_operations
none_inode_operations
;
static
const
struct
inode_operations
none_inode_operations
;
static
struct
address_space_operations
none_address_operations
;
static
struct
file_operations
none_file_operations
;
static
const
struct
file_operations
none_file_operations
;
/**
* create_xattr - create an extended attribute.
...
...
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