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
fdec29c5
Commit
fdec29c5
authored
Sep 15, 2009
by
Alex Elder
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://oss.sgi.com/xfs/xfs
into for-linus
Conflicts: fs/xfs/linux-2.6/xfs_lrw.c
parents
0cb583fd
9ef96da6
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
593 additions
and
928 deletions
+593
-928
MAINTAINERS
MAINTAINERS
+1
-1
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_aops.c
+0
-1
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_file.c
+14
-5
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_iops.c
+0
-1
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_lrw.c
+5
-3
fs/xfs/linux-2.6/xfs_stats.c
fs/xfs/linux-2.6/xfs_stats.c
+23
-28
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_super.c
+14
-10
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.c
+0
-15
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/linux-2.6/xfs_sync.h
+0
-1
fs/xfs/quota/xfs_qm_stats.c
fs/xfs/quota/xfs_qm_stats.c
+32
-46
fs/xfs/xfs_ag.h
fs/xfs/xfs_ag.h
+9
-0
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.c
+1
-1
fs/xfs/xfs_bmap.h
fs/xfs/xfs_bmap.h
+0
-11
fs/xfs/xfs_bmap_btree.c
fs/xfs/xfs_bmap_btree.c
+10
-10
fs/xfs/xfs_bmap_btree.h
fs/xfs/xfs_bmap_btree.h
+0
-1
fs/xfs/xfs_btree.c
fs/xfs/xfs_btree.c
+1
-41
fs/xfs/xfs_btree.h
fs/xfs/xfs_btree.h
+0
-15
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc.c
+406
-399
fs/xfs/xfs_ialloc.h
fs/xfs/xfs_ialloc.h
+5
-13
fs/xfs/xfs_iget.c
fs/xfs/xfs_iget.c
+0
-27
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.c
+4
-4
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode.h
+0
-8
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.c
+0
-10
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_inode_item.h
+0
-2
fs/xfs/xfs_inum.h
fs/xfs/xfs_inum.h
+0
-1
fs/xfs/xfs_itable.c
fs/xfs/xfs_itable.c
+52
-46
fs/xfs/xfs_itable.h
fs/xfs/xfs_itable.h
+0
-5
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_priv.h
+0
-2
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_log_recover.c
+1
-1
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.c
+1
-1
fs/xfs/xfs_mount.h
fs/xfs/xfs_mount.h
+0
-3
fs/xfs/xfs_mru_cache.c
fs/xfs/xfs_mru_cache.c
+0
-29
fs/xfs/xfs_mru_cache.h
fs/xfs/xfs_mru_cache.h
+0
-1
fs/xfs/xfs_rw.c
fs/xfs/xfs_rw.c
+0
-84
fs/xfs/xfs_rw.h
fs/xfs/xfs_rw.h
+0
-7
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans.h
+1
-1
fs/xfs/xfs_trans_buf.c
fs/xfs/xfs_trans_buf.c
+2
-2
fs/xfs/xfs_trans_inode.c
fs/xfs/xfs_trans_inode.c
+5
-81
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.c
+6
-11
No files found.
MAINTAINERS
View file @
fdec29c5
...
...
@@ -5694,7 +5694,7 @@ F: include/xen/
XFS FILESYSTEM
P: Silicon Graphics Inc
M:
Felix Blyakher <felixb
@sgi.com>
M:
Alex Elder <aelder
@sgi.com>
M: xfs-masters@oss.sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
...
...
fs/xfs/linux-2.6/xfs_aops.c
View file @
fdec29c5
...
...
@@ -216,7 +216,6 @@ xfs_setfilesize(
if
(
ip
->
i_d
.
di_size
<
isize
)
{
ip
->
i_d
.
di_size
=
isize
;
ip
->
i_update_core
=
1
;
ip
->
i_update_size
=
1
;
xfs_mark_inode_dirty_sync
(
ip
);
}
...
...
fs/xfs/linux-2.6/xfs_file.c
View file @
fdec29c5
...
...
@@ -172,12 +172,21 @@ xfs_file_release(
*/
STATIC
int
xfs_file_fsync
(
struct
file
*
filp
,
struct
dentry
*
dentry
,
int
datasync
)
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
{
xfs_iflags_clear
(
XFS_I
(
dentry
->
d_inode
),
XFS_ITRUNCATED
);
return
-
xfs_fsync
(
XFS_I
(
dentry
->
d_inode
));
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
xfs_inode
*
ip
=
XFS_I
(
inode
);
int
error
;
/* capture size updates in I/O completion before writing the inode. */
error
=
filemap_fdatawait
(
inode
->
i_mapping
);
if
(
error
)
return
error
;
xfs_iflags_clear
(
ip
,
XFS_ITRUNCATED
);
return
-
xfs_fsync
(
ip
);
}
STATIC
int
...
...
fs/xfs/linux-2.6/xfs_iops.c
View file @
fdec29c5
...
...
@@ -43,7 +43,6 @@
#include "xfs_error.h"
#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
...
...
fs/xfs/linux-2.6/xfs_lrw.c
View file @
fdec29c5
...
...
@@ -812,19 +812,21 @@ xfs_write(
/* Handle various SYNC-type writes */
if
((
file
->
f_flags
&
O_SYNC
)
||
IS_SYNC
(
inode
))
{
loff_t
end
=
pos
+
ret
-
1
;
int
error2
;
xfs_iunlock
(
xip
,
iolock
);
if
(
need_i_mutex
)
mutex_unlock
(
&
inode
->
i_mutex
);
error2
=
filemap_write_and_wait_range
(
mapping
,
pos
,
pos
+
ret
-
1
);
error2
=
filemap_write_and_wait_range
(
mapping
,
pos
,
end
);
if
(
!
error
)
error
=
error2
;
if
(
need_i_mutex
)
mutex_lock
(
&
inode
->
i_mutex
);
xfs_ilock
(
xip
,
iolock
);
error2
=
xfs_write_sync_logforce
(
mp
,
xip
);
error2
=
xfs_fsync
(
xip
);
if
(
!
error
)
error
=
error2
;
}
...
...
fs/xfs/linux-2.6/xfs_stats.c
View file @
fdec29c5
...
...
@@ -20,16 +20,9 @@
DEFINE_PER_CPU
(
struct
xfsstats
,
xfsstats
);
STATIC
int
xfs_read_xfsstats
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
count
,
int
*
eof
,
void
*
data
)
static
int
xfs_stat_proc_show
(
struct
seq_file
*
m
,
void
*
v
)
{
int
c
,
i
,
j
,
len
,
val
;
int
c
,
i
,
j
,
val
;
__uint64_t
xs_xstrat_bytes
=
0
;
__uint64_t
xs_write_bytes
=
0
;
__uint64_t
xs_read_bytes
=
0
;
...
...
@@ -60,18 +53,18 @@ xfs_read_xfsstats(
};
/* Loop over all stats groups */
for
(
i
=
j
=
len
=
0
;
i
<
ARRAY_SIZE
(
xstats
);
i
++
)
{
len
+=
sprintf
(
buffer
+
len
,
"%s"
,
xstats
[
i
].
desc
);
for
(
i
=
j
=
0
;
i
<
ARRAY_SIZE
(
xstats
);
i
++
)
{
seq_printf
(
m
,
"%s"
,
xstats
[
i
].
desc
);
/* inner loop does each group */
while
(
j
<
xstats
[
i
].
endpoint
)
{
val
=
0
;
/* sum over all cpus */
for_each_possible_cpu
(
c
)
val
+=
*
(((
__u32
*
)
&
per_cpu
(
xfsstats
,
c
)
+
j
));
len
+=
sprintf
(
buffer
+
len
,
" %u"
,
val
);
seq_printf
(
m
,
" %u"
,
val
);
j
++
;
}
buffer
[
len
++
]
=
'\n'
;
seq_putc
(
m
,
'\n'
)
;
}
/* extra precision counters */
for_each_possible_cpu
(
i
)
{
...
...
@@ -80,36 +73,38 @@ xfs_read_xfsstats(
xs_read_bytes
+=
per_cpu
(
xfsstats
,
i
).
xs_read_bytes
;
}
len
+=
sprintf
(
buffer
+
len
,
"xpc %Lu %Lu %Lu
\n
"
,
seq_printf
(
m
,
"xpc %Lu %Lu %Lu
\n
"
,
xs_xstrat_bytes
,
xs_write_bytes
,
xs_read_bytes
);
len
+=
sprintf
(
buffer
+
len
,
"debug %u
\n
"
,
seq_printf
(
m
,
"debug %u
\n
"
,
#if defined(DEBUG)
1
);
#else
0
);
#endif
return
0
;
}
if
(
offset
>=
len
)
{
*
start
=
buffer
;
*
eof
=
1
;
return
0
;
}
*
start
=
buffer
+
offset
;
if
((
len
-=
offset
)
>
count
)
return
count
;
*
eof
=
1
;
return
len
;
static
int
xfs_stat_proc_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
xfs_stat_proc_show
,
NULL
);
}
static
const
struct
file_operations
xfs_stat_proc_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
xfs_stat_proc_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
int
xfs_init_procfs
(
void
)
{
if
(
!
proc_mkdir
(
"fs/xfs"
,
NULL
))
goto
out
;
if
(
!
create_proc_read_entry
(
"fs/xfs/stat"
,
0
,
NULL
,
xfs_read_xfsstats
,
NULL
))
if
(
!
proc_create
(
"fs/xfs/stat"
,
0
,
NULL
,
&
xfs_stat_proc_fops
))
goto
out_remove_entry
;
return
0
;
...
...
fs/xfs/linux-2.6/xfs_super.c
View file @
fdec29c5
...
...
@@ -579,15 +579,19 @@ xfs_showargs(
else
if
(
mp
->
m_qflags
&
XFS_UQUOTA_ACCT
)
seq_puts
(
m
,
","
MNTOPT_UQUOTANOENF
);
if
(
mp
->
m_qflags
&
(
XFS_PQUOTA_ACCT
|
XFS_OQUOTA_ENFD
))
seq_puts
(
m
,
","
MNTOPT_PRJQUOTA
);
else
if
(
mp
->
m_qflags
&
XFS_PQUOTA_ACCT
)
seq_puts
(
m
,
","
MNTOPT_PQUOTANOENF
);
if
(
mp
->
m_qflags
&
(
XFS_GQUOTA_ACCT
|
XFS_OQUOTA_ENFD
))
seq_puts
(
m
,
","
MNTOPT_GRPQUOTA
);
else
if
(
mp
->
m_qflags
&
XFS_GQUOTA_ACCT
)
seq_puts
(
m
,
","
MNTOPT_GQUOTANOENF
);
/* Either project or group quotas can be active, not both */
if
(
mp
->
m_qflags
&
XFS_PQUOTA_ACCT
)
{
if
(
mp
->
m_qflags
&
XFS_OQUOTA_ENFD
)
seq_puts
(
m
,
","
MNTOPT_PRJQUOTA
);
else
seq_puts
(
m
,
","
MNTOPT_PQUOTANOENF
);
}
else
if
(
mp
->
m_qflags
&
XFS_GQUOTA_ACCT
)
{
if
(
mp
->
m_qflags
&
XFS_OQUOTA_ENFD
)
seq_puts
(
m
,
","
MNTOPT_GRPQUOTA
);
else
seq_puts
(
m
,
","
MNTOPT_GQUOTANOENF
);
}
if
(
!
(
mp
->
m_qflags
&
XFS_ALL_QUOTA_ACCT
))
seq_puts
(
m
,
","
MNTOPT_NOQUOTA
);
...
...
@@ -687,7 +691,7 @@ xfs_barrier_test(
return
error
;
}
void
STATIC
void
xfs_mountfs_check_barriers
(
xfs_mount_t
*
mp
)
{
int
error
;
...
...
fs/xfs/linux-2.6/xfs_sync.c
View file @
fdec29c5
...
...
@@ -749,21 +749,6 @@ __xfs_inode_clear_reclaim_tag(
XFS_INO_TO_AGINO
(
mp
,
ip
->
i_ino
),
XFS_ICI_RECLAIM_TAG
);
}
void
xfs_inode_clear_reclaim_tag
(
xfs_inode_t
*
ip
)
{
xfs_mount_t
*
mp
=
ip
->
i_mount
;
xfs_perag_t
*
pag
=
xfs_get_perag
(
mp
,
ip
->
i_ino
);
read_lock
(
&
pag
->
pag_ici_lock
);
spin_lock
(
&
ip
->
i_flags_lock
);
__xfs_inode_clear_reclaim_tag
(
mp
,
pag
,
ip
);
spin_unlock
(
&
ip
->
i_flags_lock
);
read_unlock
(
&
pag
->
pag_ici_lock
);
xfs_put_perag
(
mp
,
pag
);
}
STATIC
int
xfs_reclaim_inode_now
(
struct
xfs_inode
*
ip
,
...
...
fs/xfs/linux-2.6/xfs_sync.h
View file @
fdec29c5
...
...
@@ -49,7 +49,6 @@ int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
void
xfs_inode_set_reclaim_tag
(
struct
xfs_inode
*
ip
);
void
__xfs_inode_set_reclaim_tag
(
struct
xfs_perag
*
pag
,
struct
xfs_inode
*
ip
);
void
xfs_inode_clear_reclaim_tag
(
struct
xfs_inode
*
ip
);
void
__xfs_inode_clear_reclaim_tag
(
struct
xfs_mount
*
mp
,
struct
xfs_perag
*
pag
,
struct
xfs_inode
*
ip
);
...
...
fs/xfs/quota/xfs_qm_stats.c
View file @
fdec29c5
...
...
@@ -48,50 +48,34 @@
struct
xqmstats
xqmstats
;
STATIC
int
xfs_qm_read_xfsquota
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
count
,
int
*
eof
,
void
*
data
)
static
int
xqm_proc_show
(
struct
seq_file
*
m
,
void
*
v
)
{
int
len
;
/* maximum; incore; ratio free to inuse; freelist */
len
=
sprintf
(
buffer
,
"%d
\t
%d
\t
%d
\t
%u
\n
"
,
seq_printf
(
m
,
"%d
\t
%d
\t
%d
\t
%u
\n
"
,
ndquot
,
xfs_Gqm
?
atomic_read
(
&
xfs_Gqm
->
qm_totaldquots
)
:
0
,
xfs_Gqm
?
xfs_Gqm
->
qm_dqfree_ratio
:
0
,
xfs_Gqm
?
xfs_Gqm
->
qm_dqfreelist
.
qh_nelems
:
0
);
if
(
offset
>=
len
)
{
*
start
=
buffer
;
*
eof
=
1
;
return
0
;
}
*
start
=
buffer
+
offset
;
if
((
len
-=
offset
)
>
count
)
return
count
;
*
eof
=
1
;
return
len
;
return
0
;
}
STATIC
int
xfs_qm_read_stats
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
count
,
int
*
eof
,
void
*
data
)
static
int
xqm_proc_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
len
;
return
single_open
(
file
,
xqm_proc_show
,
NULL
);
}
static
const
struct
file_operations
xqm_proc_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
xqm_proc_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
int
xqmstat_proc_show
(
struct
seq_file
*
m
,
void
*
v
)
{
/* quota performance statistics */
len
=
sprintf
(
buffer
,
"qm %u %u %u %u %u %u %u %u
\n
"
,
seq_printf
(
m
,
"qm %u %u %u %u %u %u %u %u
\n
"
,
xqmstats
.
xs_qm_dqreclaims
,
xqmstats
.
xs_qm_dqreclaim_misses
,
xqmstats
.
xs_qm_dquot_dups
,
...
...
@@ -100,25 +84,27 @@ xfs_qm_read_stats(
xqmstats
.
xs_qm_dqwants
,
xqmstats
.
xs_qm_dqshake_reclaims
,
xqmstats
.
xs_qm_dqinact_reclaims
);
return
0
;
}
if
(
offset
>=
len
)
{
*
start
=
buffer
;
*
eof
=
1
;
return
0
;
}
*
start
=
buffer
+
offset
;
if
((
len
-=
offset
)
>
count
)
return
count
;
*
eof
=
1
;
return
len
;
static
int
xqmstat_proc_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
xqmstat_proc_show
,
NULL
);
}
static
const
struct
file_operations
xqmstat_proc_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
xqmstat_proc_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
void
xfs_qm_init_procfs
(
void
)
{
create_proc_read_entry
(
"fs/xfs/xqmstat"
,
0
,
NULL
,
xfs_qm_read_stats
,
NULL
);
create_proc_read_entry
(
"fs/xfs/xqm"
,
0
,
NULL
,
xfs_qm_read_xfsquota
,
NULL
);
proc_create
(
"fs/xfs/xqmstat"
,
0
,
NULL
,
&
xqmstat_proc_fops
);
proc_create
(
"fs/xfs/xqm"
,
0
,
NULL
,
&
xqm_proc_fops
);
}
void
...
...
fs/xfs/xfs_ag.h
View file @
fdec29c5
...
...
@@ -198,6 +198,15 @@ typedef struct xfs_perag
xfs_agino_t
pagi_count
;
/* number of allocated inodes */
int
pagb_count
;
/* pagb slots in use */
xfs_perag_busy_t
*
pagb_list
;
/* unstable blocks */
/*
* Inode allocation search lookup optimisation.
* If the pagino matches, the search for new inodes
* doesn't need to search the near ones again straight away
*/
xfs_agino_t
pagl_pagino
;
xfs_agino_t
pagl_leftrec
;
xfs_agino_t
pagl_rightrec
;
#ifdef __KERNEL__
spinlock_t
pagb_lock
;
/* lock for pagb_list */
...
...
fs/xfs/xfs_bmap.c
View file @
fdec29c5
...
...
@@ -3713,7 +3713,7 @@ xfs_bmap_local_to_extents(
* entry (null if none). Else, *lastxp will be set to the index
* of the found entry; *gotp will contain the entry.
*/
xfs_bmbt_rec_host_t
*
/* pointer to found extent entry */
STATIC
xfs_bmbt_rec_host_t
*
/* pointer to found extent entry */
xfs_bmap_search_multi_extents
(
xfs_ifork_t
*
ifp
,
/* inode fork pointer */
xfs_fileoff_t
bno
,
/* block number searched for */
...
...
fs/xfs/xfs_bmap.h
View file @
fdec29c5
...
...
@@ -392,17 +392,6 @@ xfs_bmap_count_blocks(
int
whichfork
,
int
*
count
);
/*
* Search the extent records for the entry containing block bno.
* If bno lies in a hole, point to the next entry. If bno lies
* past eof, *eofp will be set, and *prevp will contain the last
* entry (null if none). Else, *lastxp will be set to the index
* of the found entry; *gotp will contain the entry.
*/
xfs_bmbt_rec_host_t
*
xfs_bmap_search_multi_extents
(
struct
xfs_ifork
*
,
xfs_fileoff_t
,
int
*
,
xfs_extnum_t
*
,
xfs_bmbt_irec_t
*
,
xfs_bmbt_irec_t
*
);
#endif
/* __KERNEL__ */
#endif
/* __XFS_BMAP_H__ */
fs/xfs/xfs_bmap_btree.c
View file @
fdec29c5
...
...
@@ -202,16 +202,6 @@ xfs_bmbt_get_state(
ext_flag
);
}
/* Endian flipping versions of the bmbt extraction functions */
void
xfs_bmbt_disk_get_all
(
xfs_bmbt_rec_t
*
r
,
xfs_bmbt_irec_t
*
s
)
{
__xfs_bmbt_get_all
(
get_unaligned_be64
(
&
r
->
l0
),
get_unaligned_be64
(
&
r
->
l1
),
s
);
}
/*
* Extract the blockcount field from an on disk bmap extent record.
*/
...
...
@@ -816,6 +806,16 @@ xfs_bmbt_trace_key(
*
l1
=
0
;
}
/* Endian flipping versions of the bmbt extraction functions */
STATIC
void
xfs_bmbt_disk_get_all
(
xfs_bmbt_rec_t
*
r
,
xfs_bmbt_irec_t
*
s
)
{
__xfs_bmbt_get_all
(
get_unaligned_be64
(
&
r
->
l0
),
get_unaligned_be64
(
&
r
->
l1
),
s
);
}
STATIC
void
xfs_bmbt_trace_record
(
struct
xfs_btree_cur
*
cur
,
...
...
fs/xfs/xfs_bmap_btree.h
View file @
fdec29c5
...
...
@@ -220,7 +220,6 @@ extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
extern
xfs_fileoff_t
xfs_bmbt_get_startoff
(
xfs_bmbt_rec_host_t
*
r
);
extern
xfs_exntst_t
xfs_bmbt_get_state
(
xfs_bmbt_rec_host_t
*
r
);
extern
void
xfs_bmbt_disk_get_all
(
xfs_bmbt_rec_t
*
r
,
xfs_bmbt_irec_t
*
s
);
extern
xfs_filblks_t
xfs_bmbt_disk_get_blockcount
(
xfs_bmbt_rec_t
*
r
);
extern
xfs_fileoff_t
xfs_bmbt_disk_get_startoff
(
xfs_bmbt_rec_t
*
r
);
...
...
fs/xfs/xfs_btree.c
View file @
fdec29c5
...
...
@@ -645,46 +645,6 @@ xfs_btree_read_bufl(
return
0
;
}
/*
* Get a buffer for the block, return it read in.
* Short-form addressing.
*/
int
/* error */
xfs_btree_read_bufs
(
xfs_mount_t
*
mp
,
/* file system mount point */
xfs_trans_t
*
tp
,
/* transaction pointer */
xfs_agnumber_t
agno
,
/* allocation group number */
xfs_agblock_t
agbno
,
/* allocation group block number */
uint
lock
,
/* lock flags for read_buf */
xfs_buf_t
**
bpp
,
/* buffer for agno/agbno */
int
refval
)
/* ref count value for buffer */
{
xfs_buf_t
*
bp
;
/* return value */
xfs_daddr_t
d
;
/* real disk block address */
int
error
;
ASSERT
(
agno
!=
NULLAGNUMBER
);
ASSERT
(
agbno
!=
NULLAGBLOCK
);
d
=
XFS_AGB_TO_DADDR
(
mp
,
agno
,
agbno
);
if
((
error
=
xfs_trans_read_buf
(
mp
,
tp
,
mp
->
m_ddev_targp
,
d
,
mp
->
m_bsize
,
lock
,
&
bp
)))
{
return
error
;
}
ASSERT
(
!
bp
||
!
XFS_BUF_GETERROR
(
bp
));
if
(
bp
!=
NULL
)
{
switch
(
refval
)
{
case
XFS_ALLOC_BTREE_REF
:
XFS_BUF_SET_VTYPE_REF
(
bp
,
B_FS_MAP
,
refval
);
break
;
case
XFS_INO_BTREE_REF
:
XFS_BUF_SET_VTYPE_REF
(
bp
,
B_FS_INOMAP
,
refval
);
break
;
}
}
*
bpp
=
bp
;
return
0
;
}
/*
* Read-ahead the block, don't wait for it, don't return a buffer.
* Long-form addressing.
...
...
@@ -2951,7 +2911,7 @@ xfs_btree_insert(
* inode we have to copy the single block it was pointing to into the
* inode.
*/
int
STATIC
int
xfs_btree_kill_iroot
(
struct
xfs_btree_cur
*
cur
)
{
...
...
fs/xfs/xfs_btree.h
View file @
fdec29c5
...
...
@@ -378,20 +378,6 @@ xfs_btree_read_bufl(
struct
xfs_buf
**
bpp
,
/* buffer for fsbno */
int
refval
);
/* ref count value for buffer */
/*
* Get a buffer for the block, return it read in.
* Short-form addressing.
*/
int
/* error */
xfs_btree_read_bufs
(
struct
xfs_mount
*
mp
,
/* file system mount point */
struct
xfs_trans
*
tp
,
/* transaction pointer */
xfs_agnumber_t
agno
,
/* allocation group number */
xfs_agblock_t
agbno
,
/* allocation group block number */
uint
lock
,
/* lock flags for read_buf */
struct
xfs_buf
**
bpp
,
/* buffer for agno/agbno */
int
refval
);
/* ref count value for buffer */
/*
* Read-ahead the block, don't wait for it, don't return a buffer.
* Long-form addressing.
...
...
@@ -432,7 +418,6 @@ int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
int
xfs_btree_lookup
(
struct
xfs_btree_cur
*
,
xfs_lookup_t
,
int
*
);
int
xfs_btree_update
(
struct
xfs_btree_cur
*
,
union
xfs_btree_rec
*
);
int
xfs_btree_new_iroot
(
struct
xfs_btree_cur
*
,
int
*
,
int
*
);
int
xfs_btree_kill_iroot
(
struct
xfs_btree_cur
*
);
int
xfs_btree_insert
(
struct
xfs_btree_cur
*
,
int
*
);
int
xfs_btree_delete
(
struct
xfs_btree_cur
*
,
int
*
);
int
xfs_btree_get_rec
(
struct
xfs_btree_cur
*
,
union
xfs_btree_rec
**
,
int
*
);
...
...
fs/xfs/xfs_ialloc.c
View file @
fdec29c5
...
...
@@ -57,75 +57,35 @@ xfs_ialloc_cluster_alignment(
}
/*
* Lookup the record equal to ino in the btree given by cur.
*/
STATIC
int
/* error */
xfs_inobt_lookup_eq
(
struct
xfs_btree_cur
*
cur
,
/* btree cursor */
xfs_agino_t
ino
,
/* starting inode of chunk */
__int32_t
fcnt
,
/* free inode count */
xfs_inofree_t
free
,
/* free inode mask */
int
*
stat
)
/* success/failure */
{
cur
->
bc_rec
.
i
.
ir_startino
=
ino
;
cur
->
bc_rec
.
i
.
ir_freecount
=
fcnt
;
cur
->
bc_rec
.
i
.
ir_free
=
free
;
return
xfs_btree_lookup
(
cur
,
XFS_LOOKUP_EQ
,
stat
);
}
/*
* Lookup the first record greater than or equal to ino
* in the btree given by cur.
* Lookup a record by ino in the btree given by cur.
*/
int
/* error */
xfs_inobt_lookup
_ge
(
xfs_inobt_lookup
(
struct
xfs_btree_cur
*
cur
,
/* btree cursor */
xfs_agino_t
ino
,
/* starting inode of chunk */
__int32_t
fcnt
,
/* free inode count */
xfs_inofree_t
free
,
/* free inode mask */
xfs_lookup_t
dir
,
/* <=, >=, == */
int
*
stat
)
/* success/failure */
{
cur
->
bc_rec
.
i
.
ir_startino
=
ino
;
cur
->
bc_rec
.
i
.
ir_freecount
=
fcnt
;
cur
->
bc_rec
.
i
.
ir_free
=
free
;
return
xfs_btree_lookup
(
cur
,
XFS_LOOKUP_GE
,
stat
);
cur
->
bc_rec
.
i
.
ir_freecount
=
0
;
cur
->
bc_rec
.
i
.
ir_free
=
0
;
return
xfs_btree_lookup
(
cur
,
dir
,
stat
);
}
/*
* Lookup the first record less than or equal to ino
* in the btree given by cur.
*/
int
/* error */
xfs_inobt_lookup_le
(
struct
xfs_btree_cur
*
cur
,
/* btree cursor */
xfs_agino_t
ino
,
/* starting inode of chunk */
__int32_t
fcnt
,
/* free inode count */
xfs_inofree_t
free
,
/* free inode mask */
int
*
stat
)
/* success/failure */
{
cur
->
bc_rec
.
i
.
ir_startino
=
ino
;
cur
->
bc_rec
.
i
.
ir_freecount
=
fcnt
;
cur
->
bc_rec
.
i
.
ir_free
=
free
;
return
xfs_btree_lookup
(
cur
,
XFS_LOOKUP_LE
,
stat
);
}
/*
* Update the record referred to by cur to the value given
* by [ino, fcnt, free].
* Update the record referred to by cur to the value given.
* This either works (return 0) or gets an EFSCORRUPTED error.
*/
STATIC
int
/* error */
xfs_inobt_update
(
struct
xfs_btree_cur
*
cur
,
/* btree cursor */
xfs_agino_t
ino
,
/* starting inode of chunk */
__int32_t
fcnt
,
/* free inode count */
xfs_inofree_t
free
)
/* free inode mask */
xfs_inobt_rec_incore_t
*
irec
)
/* btree record */
{
union
xfs_btree_rec
rec
;
rec
.
inobt
.
ir_startino
=
cpu_to_be32
(
ino
);
rec
.
inobt
.
ir_freecount
=
cpu_to_be32
(
fc
nt
);
rec
.
inobt
.
ir_free
=
cpu_to_be64
(
free
);
rec
.
inobt
.
ir_startino
=
cpu_to_be32
(
i
rec
->
ir_starti
no
);
rec
.
inobt
.
ir_freecount
=
cpu_to_be32
(
irec
->
ir_freecou
nt
);
rec
.
inobt
.
ir_free
=
cpu_to_be64
(
irec
->
ir_
free
);
return
xfs_btree_update
(
cur
,
&
rec
);
}
...
...
@@ -135,9 +95,7 @@ xfs_inobt_update(
int
/* error */
xfs_inobt_get_rec
(
struct
xfs_btree_cur
*
cur
,
/* btree cursor */
xfs_agino_t
*
ino
,
/* output: starting inode of chunk */
__int32_t
*
fcnt
,
/* output: number of free inodes */
xfs_inofree_t
*
free
,
/* output: free inode mask */
xfs_inobt_rec_incore_t
*
irec
,
/* btree record */
int
*
stat
)
/* output: success/failure */
{
union
xfs_btree_rec
*
rec
;
...
...
@@ -145,13 +103,135 @@ xfs_inobt_get_rec(
error
=
xfs_btree_get_rec
(
cur
,
&
rec
,
stat
);
if
(
!
error
&&
*
stat
==
1
)
{
*
ino
=
be32_to_cpu
(
rec
->
inobt
.
ir_startino
);
*
fc
nt
=
be32_to_cpu
(
rec
->
inobt
.
ir_freecount
);
*
free
=
be64_to_cpu
(
rec
->
inobt
.
ir_free
);
irec
->
ir_start
ino
=
be32_to_cpu
(
rec
->
inobt
.
ir_startino
);
irec
->
ir_freecou
nt
=
be32_to_cpu
(
rec
->
inobt
.
ir_freecount
);
irec
->
ir_
free
=
be64_to_cpu
(
rec
->
inobt
.
ir_free
);
}
return
error
;
}
/*
* Verify that the number of free inodes in the AGI is correct.
*/
#ifdef DEBUG
STATIC
int
xfs_check_agi_freecount
(
struct
xfs_btree_cur
*
cur
,
struct
xfs_agi
*
agi
)
{
if
(
cur
->
bc_nlevels
==
1
)
{
xfs_inobt_rec_incore_t
rec
;
int
freecount
=
0
;
int
error
;
int
i
;
error
=
xfs_inobt_lookup
(
cur
,
0
,
XFS_LOOKUP_GE
,
&
i
);
if
(
error
)
return
error
;
do
{
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
,
&
i
);
if
(
error
)
return
error
;
if
(
i
)
{
freecount
+=
rec
.
ir_freecount
;
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
);
if
(
error
)
return
error
;
}
}
while
(
i
==
1
);
if
(
!
XFS_FORCED_SHUTDOWN
(
cur
->
bc_mp
))
ASSERT
(
freecount
==
be32_to_cpu
(
agi
->
agi_freecount
));
}
return
0
;
}
#else
#define xfs_check_agi_freecount(cur, agi) 0
#endif
/*
* Initialise a new set of inodes.
*/
STATIC
void
xfs_ialloc_inode_init
(
struct
xfs_mount
*
mp
,
struct
xfs_trans
*
tp
,
xfs_agnumber_t
agno
,
xfs_agblock_t
agbno
,
xfs_agblock_t
length
,
unsigned
int
gen
)
{
struct
xfs_buf
*
fbuf
;
struct
xfs_dinode
*
free
;
int
blks_per_cluster
,
nbufs
,
ninodes
;
int
version
;
int
i
,
j
;
xfs_daddr_t
d
;
/*
* Loop over the new block(s), filling in the inodes.
* For small block sizes, manipulate the inodes in buffers
* which are multiples of the blocks size.
*/
if
(
mp
->
m_sb
.
sb_blocksize
>=
XFS_INODE_CLUSTER_SIZE
(
mp
))
{
blks_per_cluster
=
1
;
nbufs
=
length
;
ninodes
=
mp
->
m_sb
.
sb_inopblock
;
}
else
{
blks_per_cluster
=
XFS_INODE_CLUSTER_SIZE
(
mp
)
/
mp
->
m_sb
.
sb_blocksize
;
nbufs
=
length
/
blks_per_cluster
;
ninodes
=
blks_per_cluster
*
mp
->
m_sb
.
sb_inopblock
;
}
/*
* Figure out what version number to use in the inodes we create.
* If the superblock version has caught up to the one that supports
* the new inode format, then use the new inode version. Otherwise
* use the old version so that old kernels will continue to be
* able to use the file system.
*/
if
(
xfs_sb_version_hasnlink
(
&
mp
->
m_sb
))
version
=
2
;
else
version
=
1
;
for
(
j
=
0
;
j
<
nbufs
;
j
++
)
{
/*
* Get the block.
*/
d
=
XFS_AGB_TO_DADDR
(
mp
,
agno
,
agbno
+
(
j
*
blks_per_cluster
));
fbuf
=
xfs_trans_get_buf
(
tp
,
mp
->
m_ddev_targp
,
d
,
mp
->
m_bsize
*
blks_per_cluster
,
XFS_BUF_LOCK
);
ASSERT
(
fbuf
);
ASSERT
(
!
XFS_BUF_GETERROR
(
fbuf
));
/*
* Initialize all inodes in this buffer and then log them.
*
* XXX: It would be much better if we had just one transaction
* to log a whole cluster of inodes instead of all the
* individual transactions causing a lot of log traffic.
*/
xfs_biozero
(
fbuf
,
0
,
ninodes
<<
mp
->
m_sb
.
sb_inodelog
);
for
(
i
=
0
;
i
<
ninodes
;
i
++
)
{
int
ioffset
=
i
<<
mp
->
m_sb
.
sb_inodelog
;
uint
isize
=
sizeof
(
struct
xfs_dinode
);
free
=
xfs_make_iptr
(
mp
,
fbuf
,
i
);
free
->
di_magic
=
cpu_to_be16
(
XFS_DINODE_MAGIC
);
free
->
di_version
=
version
;
free
->
di_gen
=
cpu_to_be32
(
gen
);
free
->
di_next_unlinked
=
cpu_to_be32
(
NULLAGINO
);
xfs_trans_log_buf
(
tp
,
fbuf
,
ioffset
,
ioffset
+
isize
-
1
);
}
xfs_trans_inode_alloc_buf
(
tp
,
fbuf
);
}
}
/*
* Allocate new inodes in the allocation group specified by agbp.
* Return 0 for success, else error code.
...
...
@@ -164,24 +244,15 @@ xfs_ialloc_ag_alloc(
{
xfs_agi_t
*
agi
;
/* allocation group header */
xfs_alloc_arg_t
args
;
/* allocation argument structure */
int
blks_per_cluster
;
/* fs blocks per inode cluster */
xfs_btree_cur_t
*
cur
;
/* inode btree cursor */
xfs_daddr_t
d
;
/* disk addr of buffer */
xfs_agnumber_t
agno
;
int
error
;
xfs_buf_t
*
fbuf
;
/* new free inodes' buffer */
xfs_dinode_t
*
free
;
/* new free inode structure */
int
i
;
/* inode counter */
int
j
;
/* block counter */
int
nbufs
;
/* num bufs of new inodes */
int
i
;
xfs_agino_t
newino
;
/* new first inode's number */
xfs_agino_t
newlen
;
/* new number of inodes */
int
ninodes
;
/* num inodes per buf */
xfs_agino_t
thisino
;
/* current inode number, for loop */
int
version
;
/* inode version number to use */
int
isaligned
=
0
;
/* inode allocation at stripe unit */
/* boundary */
unsigned
int
gen
;
args
.
tp
=
tp
;
args
.
mp
=
tp
->
t_mountp
;
...
...
@@ -202,12 +273,12 @@ xfs_ialloc_ag_alloc(
*/
agi
=
XFS_BUF_TO_AGI
(
agbp
);
newino
=
be32_to_cpu
(
agi
->
agi_newino
);
agno
=
be32_to_cpu
(
agi
->
agi_seqno
);
args
.
agbno
=
XFS_AGINO_TO_AGBNO
(
args
.
mp
,
newino
)
+
XFS_IALLOC_BLOCKS
(
args
.
mp
);
if
(
likely
(
newino
!=
NULLAGINO
&&
(
args
.
agbno
<
be32_to_cpu
(
agi
->
agi_length
))))
{
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
be32_to_cpu
(
agi
->
agi_seqno
),
args
.
agbno
);
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
agno
,
args
.
agbno
);
args
.
type
=
XFS_ALLOCTYPE_THIS_BNO
;
args
.
mod
=
args
.
total
=
args
.
wasdel
=
args
.
isfl
=
args
.
userdata
=
args
.
minalignslop
=
0
;
...
...
@@ -258,8 +329,7 @@ xfs_ialloc_ag_alloc(
* For now, just allocate blocks up front.
*/
args
.
agbno
=
be32_to_cpu
(
agi
->
agi_root
);
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
be32_to_cpu
(
agi
->
agi_seqno
),
args
.
agbno
);
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
agno
,
args
.
agbno
);
/*
* Allocate a fixed-size extent of inodes.
*/
...
...
@@ -282,8 +352,7 @@ xfs_ialloc_ag_alloc(
if
(
isaligned
&&
args
.
fsbno
==
NULLFSBLOCK
)
{
args
.
type
=
XFS_ALLOCTYPE_NEAR_BNO
;
args
.
agbno
=
be32_to_cpu
(
agi
->
agi_root
);
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
be32_to_cpu
(
agi
->
agi_seqno
),
args
.
agbno
);
args
.
fsbno
=
XFS_AGB_TO_FSB
(
args
.
mp
,
agno
,
args
.
agbno
);
args
.
alignment
=
xfs_ialloc_cluster_alignment
(
&
args
);
if
((
error
=
xfs_alloc_vextent
(
&
args
)))
return
error
;
...
...
@@ -294,85 +363,30 @@ xfs_ialloc_ag_alloc(
return
0
;
}
ASSERT
(
args
.
len
==
args
.
minlen
);
/*
* Convert the results.
*/
newino
=
XFS_OFFBNO_TO_AGINO
(
args
.
mp
,
args
.
agbno
,
0
);
/*
* Loop over the new block(s), filling in the inodes.
* For small block sizes, manipulate the inodes in buffers
* which are multiples of the blocks size.
*/
if
(
args
.
mp
->
m_sb
.
sb_blocksize
>=
XFS_INODE_CLUSTER_SIZE
(
args
.
mp
))
{
blks_per_cluster
=
1
;
nbufs
=
(
int
)
args
.
len
;
ninodes
=
args
.
mp
->
m_sb
.
sb_inopblock
;
}
else
{
blks_per_cluster
=
XFS_INODE_CLUSTER_SIZE
(
args
.
mp
)
/
args
.
mp
->
m_sb
.
sb_blocksize
;
nbufs
=
(
int
)
args
.
len
/
blks_per_cluster
;
ninodes
=
blks_per_cluster
*
args
.
mp
->
m_sb
.
sb_inopblock
;
}
/*
* Figure out what version number to use in the inodes we create.
* If the superblock version has caught up to the one that supports
* the new inode format, then use the new inode version. Otherwise
* use the old version so that old kernels will continue to be
* able to use the file system.
*/
if
(
xfs_sb_version_hasnlink
(
&
args
.
mp
->
m_sb
))
version
=
2
;
else
version
=
1
;
/*
* Stamp and write the inode buffers.
*
* Seed the new inode cluster with a random generation number. This
* prevents short-term reuse of generation numbers if a chunk is
* freed and then immediately reallocated. We use random numbers
* rather than a linear progression to prevent the next generation
* number from being easily guessable.
*/
gen
=
random32
();
for
(
j
=
0
;
j
<
nbufs
;
j
++
)
{
/*
* Get the block.
*/
d
=
XFS_AGB_TO_DADDR
(
args
.
mp
,
be32_to_cpu
(
agi
->
agi_seqno
),
args
.
agbno
+
(
j
*
blks_per_cluster
));
fbuf
=
xfs_trans_get_buf
(
tp
,
args
.
mp
->
m_ddev_targp
,
d
,
args
.
mp
->
m_bsize
*
blks_per_cluster
,
XFS_BUF_LOCK
);
ASSERT
(
fbuf
);
ASSERT
(
!
XFS_BUF_GETERROR
(
fbuf
));
xfs_ialloc_inode_init
(
args
.
mp
,
tp
,
agno
,
args
.
agbno
,
args
.
len
,
random32
());
/*
* Initialize all inodes in this buffer and then log them.
*
* XXX: It would be much better if we had just one transaction to
* log a whole cluster of inodes instead of all the individual
* transactions causing a lot of log traffic.
*/
xfs_biozero
(
fbuf
,
0
,
ninodes
<<
args
.
mp
->
m_sb
.
sb_inodelog
);
for
(
i
=
0
;
i
<
ninodes
;
i
++
)
{
int
ioffset
=
i
<<
args
.
mp
->
m_sb
.
sb_inodelog
;
uint
isize
=
sizeof
(
struct
xfs_dinode
);
free
=
xfs_make_iptr
(
args
.
mp
,
fbuf
,
i
);
free
->
di_magic
=
cpu_to_be16
(
XFS_DINODE_MAGIC
);
free
->
di_version
=
version
;
free
->
di_gen
=
cpu_to_be32
(
gen
);
free
->
di_next_unlinked
=
cpu_to_be32
(
NULLAGINO
);
xfs_trans_log_buf
(
tp
,
fbuf
,
ioffset
,
ioffset
+
isize
-
1
);
}
xfs_trans_inode_alloc_buf
(
tp
,
fbuf
);
}
/*
* Convert the results.
*/
newino
=
XFS_OFFBNO_TO_AGINO
(
args
.
mp
,
args
.
agbno
,
0
);
be32_add_cpu
(
&
agi
->
agi_count
,
newlen
);
be32_add_cpu
(
&
agi
->
agi_freecount
,
newlen
);
agno
=
be32_to_cpu
(
agi
->
agi_seqno
);
down_read
(
&
args
.
mp
->
m_peraglock
);
args
.
mp
->
m_perag
[
agno
].
pagi_freecount
+=
newlen
;
up_read
(
&
args
.
mp
->
m_peraglock
);
agi
->
agi_newino
=
cpu_to_be32
(
newino
);
/*
* Insert records describing the new inode chunk into the btree.
*/
...
...
@@ -380,13 +394,17 @@ xfs_ialloc_ag_alloc(
for
(
thisino
=
newino
;
thisino
<
newino
+
newlen
;
thisino
+=
XFS_INODES_PER_CHUNK
)
{
if
((
error
=
xfs_inobt_lookup_eq
(
cur
,
thisino
,
XFS_INODES_PER_CHUNK
,
XFS_INOBT_ALL_FREE
,
&
i
)))
{
cur
->
bc_rec
.
i
.
ir_startino
=
thisino
;
cur
->
bc_rec
.
i
.
ir_freecount
=
XFS_INODES_PER_CHUNK
;
cur
->
bc_rec
.
i
.
ir_free
=
XFS_INOBT_ALL_FREE
;
error
=
xfs_btree_lookup
(
cur
,
XFS_LOOKUP_EQ
,
&
i
);
if
(
error
)
{
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_ERROR
);
return
error
;
}
ASSERT
(
i
==
0
);
if
((
error
=
xfs_btree_insert
(
cur
,
&
i
)))
{
error
=
xfs_btree_insert
(
cur
,
&
i
);
if
(
error
)
{
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_ERROR
);
return
error
;
}
...
...
@@ -538,6 +556,62 @@ xfs_ialloc_ag_select(
}
}
/*
* Try to retrieve the next record to the left/right from the current one.
*/
STATIC
int
xfs_ialloc_next_rec
(
struct
xfs_btree_cur
*
cur
,
xfs_inobt_rec_incore_t
*
rec
,
int
*
done
,
int
left
)
{
int
error
;
int
i
;
if
(
left
)
error
=
xfs_btree_decrement
(
cur
,
0
,
&
i
);
else
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
);
if
(
error
)
return
error
;
*
done
=
!
i
;
if
(
i
)
{
error
=
xfs_inobt_get_rec
(
cur
,
rec
,
&
i
);
if
(
error
)
return
error
;
XFS_WANT_CORRUPTED_RETURN
(
i
==
1
);
}
return
0
;
}
STATIC
int
xfs_ialloc_get_rec
(
struct
xfs_btree_cur
*
cur
,
xfs_agino_t
agino
,
xfs_inobt_rec_incore_t
*
rec
,
int
*
done
,
int
left
)
{
int
error
;
int
i
;
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_EQ
,
&
i
);
if
(
error
)
return
error
;
*
done
=
!
i
;
if
(
i
)
{
error
=
xfs_inobt_get_rec
(
cur
,
rec
,
&
i
);
if
(
error
)
return
error
;
XFS_WANT_CORRUPTED_RETURN
(
i
==
1
);
}
return
0
;
}
/*
* Visible inode allocation functions.
*/
...
...
@@ -592,8 +666,8 @@ xfs_dialloc(
int
j
;
/* result code */
xfs_mount_t
*
mp
;
/* file system mount structure */
int
offset
;
/* index of inode in chunk */
xfs_agino_t
pagino
;
/* parent's
a.g.
relative inode # */
xfs_agnumber_t
pagno
;
/* parent's
allocation group
number */
xfs_agino_t
pagino
;
/* parent's
AG
relative inode # */
xfs_agnumber_t
pagno
;
/* parent's
AG
number */
xfs_inobt_rec_incore_t
rec
;
/* inode allocation record */
xfs_agnumber_t
tagno
;
/* testing allocation group number */
xfs_btree_cur_t
*
tcur
;
/* temp cursor */
...
...
@@ -716,6 +790,8 @@ xfs_dialloc(
*/
agno
=
tagno
;
*
IO_agbp
=
NULL
;
restart_pagno:
cur
=
xfs_inobt_init_cursor
(
mp
,
tp
,
agbp
,
be32_to_cpu
(
agi
->
agi_seqno
));
/*
* If pagino is 0 (this is the root inode allocation) use newino.
...
...
@@ -723,220 +799,199 @@ xfs_dialloc(
*/
if
(
!
pagino
)
pagino
=
be32_to_cpu
(
agi
->
agi_newino
);
#ifdef DEBUG
if
(
cur
->
bc_nlevels
==
1
)
{
int
freecount
=
0
;
if
((
error
=
xfs_inobt_lookup_ge
(
cur
,
0
,
0
,
0
,
&
i
)))
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
do
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
freecount
+=
rec
.
ir_freecount
;
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error0
;
}
while
(
i
==
1
);
error
=
xfs_check_agi_freecount
(
cur
,
agi
);
if
(
error
)
goto
error0
;
ASSERT
(
freecount
==
be32_to_cpu
(
agi
->
agi_freecount
)
||
XFS_FORCED_SHUTDOWN
(
mp
));
}
#endif
/*
* If in the same
a.g.
as the parent, try to get near the parent.
* If in the same
AG
as the parent, try to get near the parent.
*/
if
(
pagno
==
agno
)
{
if
((
error
=
xfs_inobt_lookup_le
(
cur
,
pagino
,
0
,
0
,
&
i
)))
xfs_perag_t
*
pag
=
&
mp
->
m_perag
[
agno
];
int
doneleft
;
/* done, to the left */
int
doneright
;
/* done, to the right */
int
searchdistance
=
10
;
error
=
xfs_inobt_lookup
(
cur
,
pagino
,
XFS_LOOKUP_LE
,
&
i
);
if
(
error
)
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
,
&
j
);
if
(
error
)
goto
error0
;
if
(
i
!=
0
&&
(
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
j
))
==
0
&&
j
==
1
&&
rec
.
ir_freecount
>
0
)
{
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
if
(
rec
.
ir_freecount
>
0
)
{
/*
* Found a free inode in the same chunk
* as parent, done.
* as
the
parent, done.
*/
goto
alloc_inode
;
}
/*
* In the same AG as parent, but parent's chunk is full.
*/
/* duplicate the cursor, search left & right simultaneously */
error
=
xfs_btree_dup_cursor
(
cur
,
&
tcur
);
if
(
error
)
goto
error0
;
/*
*
In the same a.g. as parent, but parent's chunk is full
.
*
Skip to last blocks looked up if same parent inode
.
*/
else
{
int
doneleft
;
/* done, to the left */
int
doneright
;
/* done, to the right */
if
(
pagino
!=
NULLAGINO
&&
pag
->
pagl_pagino
==
pagino
&&
pag
->
pagl_leftrec
!=
NULLAGINO
&&
pag
->
pagl_rightrec
!=
NULLAGINO
)
{
error
=
xfs_ialloc_get_rec
(
tcur
,
pag
->
pagl_leftrec
,
&
trec
,
&
doneleft
,
1
);
if
(
error
)
goto
error1
;
error
=
xfs_ialloc_get_rec
(
cur
,
pag
->
pagl_rightrec
,
&
rec
,
&
doneright
,
0
);
if
(
error
)
goto
error0
;
ASSERT
(
i
==
1
);
ASSERT
(
j
==
1
);
/*
* Duplicate the cursor, search left & right
* simultaneously.
*/
if
((
error
=
xfs_btree_dup_cursor
(
cur
,
&
tcur
)))
goto
error0
;
/*
* Search left with tcur, back up 1 record.
*/
if
((
error
=
xfs_btree_decrement
(
tcur
,
0
,
&
i
)))
goto
error1
;
doneleft
=
!
i
;
if
(
!
doneleft
)
{
if
((
error
=
xfs_inobt_get_rec
(
tcur
,
&
trec
.
ir_startino
,
&
trec
.
ir_freecount
,
&
trec
.
ir_free
,
&
i
)))
goto
error1
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error1
);
}
/*
* Search right with cur, go forward 1 record.
*/
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
}
else
{
/* search left with tcur, back up 1 record */
error
=
xfs_ialloc_next_rec
(
tcur
,
&
trec
,
&
doneleft
,
1
);
if
(
error
)
goto
error1
;
doneright
=
!
i
;
if
(
!
doneright
)
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error1
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error1
);
}
/*
* Loop until we find the closest inode chunk
* with a free one.
*/
while
(
!
doneleft
||
!
doneright
)
{
int
useleft
;
/* using left inode
chunk this time */
/* search right with cur, go forward 1 record. */
error
=
xfs_ialloc_next_rec
(
cur
,
&
rec
,
&
doneright
,
0
);
if
(
error
)
goto
error1
;
}
/*
* Loop until we find an inode chunk with a free inode.
*/
while
(
!
doneleft
||
!
doneright
)
{
int
useleft
;
/* using left inode chunk this time */
if
(
!--
searchdistance
)
{
/*
* Figure out which block is closer,
* if both are valid.
*/
if
(
!
doneleft
&&
!
doneright
)
useleft
=
pagino
-
(
trec
.
ir_startino
+
XFS_INODES_PER_CHUNK
-
1
)
<
rec
.
ir_startino
-
pagino
;
else
useleft
=
!
doneleft
;
/*
* If checking the left, does it have
* free inodes?
*/
if
(
useleft
&&
trec
.
ir_freecount
)
{
/*
* Yes, set it up as the chunk to use.
*/
rec
=
trec
;
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
cur
=
tcur
;
break
;
}
/*
* If checking the right, does it have
* free inodes?
*/
if
(
!
useleft
&&
rec
.
ir_freecount
)
{
/*
* Yes, it's already set up.
*/
xfs_btree_del_cursor
(
tcur
,
XFS_BTREE_NOERROR
);
break
;
}
/*
* If used the left, get another one
* further left.
*/
if
(
useleft
)
{
if
((
error
=
xfs_btree_decrement
(
tcur
,
0
,
&
i
)))
goto
error1
;
doneleft
=
!
i
;
if
(
!
doneleft
)
{
if
((
error
=
xfs_inobt_get_rec
(
tcur
,
&
trec
.
ir_startino
,
&
trec
.
ir_freecount
,
&
trec
.
ir_free
,
&
i
)))
goto
error1
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error1
);
}
}
/*
* If used the right, get another one
* further right.
* Not in range - save last search
* location and allocate a new inode
*/
else
{
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error1
;
doneright
=
!
i
;
if
(
!
doneright
)
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error1
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error1
);
}
}
pag
->
pagl_leftrec
=
trec
.
ir_startino
;
pag
->
pagl_rightrec
=
rec
.
ir_startino
;
pag
->
pagl_pagino
=
pagino
;
goto
newino
;
}
/* figure out the closer block if both are valid. */
if
(
!
doneleft
&&
!
doneright
)
{
useleft
=
pagino
-
(
trec
.
ir_startino
+
XFS_INODES_PER_CHUNK
-
1
)
<
rec
.
ir_startino
-
pagino
;
}
else
{
useleft
=
!
doneleft
;
}
ASSERT
(
!
doneleft
||
!
doneright
);
/* free inodes to the left? */
if
(
useleft
&&
trec
.
ir_freecount
)
{
rec
=
trec
;
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
cur
=
tcur
;
pag
->
pagl_leftrec
=
trec
.
ir_startino
;
pag
->
pagl_rightrec
=
rec
.
ir_startino
;
pag
->
pagl_pagino
=
pagino
;
goto
alloc_inode
;
}
/* free inodes to the right? */
if
(
!
useleft
&&
rec
.
ir_freecount
)
{
xfs_btree_del_cursor
(
tcur
,
XFS_BTREE_NOERROR
);
pag
->
pagl_leftrec
=
trec
.
ir_startino
;
pag
->
pagl_rightrec
=
rec
.
ir_startino
;
pag
->
pagl_pagino
=
pagino
;
goto
alloc_inode
;
}
/* get next record to check */
if
(
useleft
)
{
error
=
xfs_ialloc_next_rec
(
tcur
,
&
trec
,
&
doneleft
,
1
);
}
else
{
error
=
xfs_ialloc_next_rec
(
cur
,
&
rec
,
&
doneright
,
0
);
}
if
(
error
)
goto
error1
;
}
/*
* We've reached the end of the btree. because
* we are only searching a small chunk of the
* btree each search, there is obviously free
* inodes closer to the parent inode than we
* are now. restart the search again.
*/
pag
->
pagl_pagino
=
NULLAGINO
;
pag
->
pagl_leftrec
=
NULLAGINO
;
pag
->
pagl_rightrec
=
NULLAGINO
;
xfs_btree_del_cursor
(
tcur
,
XFS_BTREE_NOERROR
);
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
goto
restart_pagno
;
}
/*
* In a different
a.g.
from the parent.
* In a different
AG
from the parent.
* See if the most recently allocated block has any free.
*/
else
if
(
be32_to_cpu
(
agi
->
agi_newino
)
!=
NULLAGINO
)
{
if
((
error
=
xfs_inobt_lookup_eq
(
cur
,
be32_to_cpu
(
agi
->
agi_newino
),
0
,
0
,
&
i
)))
newino:
if
(
be32_to_cpu
(
agi
->
agi_newino
)
!=
NULLAGINO
)
{
error
=
xfs_inobt_lookup
(
cur
,
be32_to_cpu
(
agi
->
agi_newino
),
XFS_LOOKUP_EQ
,
&
i
);
if
(
error
)
goto
error0
;
if
(
i
==
1
&&
(
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
j
))
==
0
&&
j
==
1
&&
rec
.
ir_freecount
>
0
)
{
/*
* The last chunk allocated in the group still has
* a free inode.
*/
}
/*
* None left in the last group, search the whole a.g.
*/
else
{
if
(
i
==
1
)
{
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
,
&
j
);
if
(
error
)
goto
error0
;
if
((
error
=
xfs_inobt_lookup_ge
(
cur
,
0
,
0
,
0
,
&
i
)))
goto
error0
;
ASSERT
(
i
==
1
);
for
(;;)
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
if
(
rec
.
ir_freecount
>
0
)
break
;
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
if
(
j
==
1
&&
rec
.
ir_freecount
>
0
)
{
/*
* The last chunk allocated in the group
* still has a free inode.
*/
goto
alloc_inode
;
}
}
}
/*
* None left in the last group, search the whole AG
*/
error
=
xfs_inobt_lookup
(
cur
,
0
,
XFS_LOOKUP_GE
,
&
i
);
if
(
error
)
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
for
(;;)
{
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
,
&
i
);
if
(
error
)
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
if
(
rec
.
ir_freecount
>
0
)
break
;
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
);
if
(
error
)
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
}
alloc_inode:
offset
=
xfs_ialloc_find_free
(
&
rec
.
ir_free
);
ASSERT
(
offset
>=
0
);
ASSERT
(
offset
<
XFS_INODES_PER_CHUNK
);
...
...
@@ -945,33 +1000,19 @@ xfs_dialloc(
ino
=
XFS_AGINO_TO_INO
(
mp
,
agno
,
rec
.
ir_startino
+
offset
);
rec
.
ir_free
&=
~
XFS_INOBT_MASK
(
offset
);
rec
.
ir_freecount
--
;
if
((
error
=
xfs_inobt_update
(
cur
,
rec
.
ir_startino
,
rec
.
ir_freecount
,
rec
.
ir_free
))
)
error
=
xfs_inobt_update
(
cur
,
&
rec
);
if
(
error
)
goto
error0
;
be32_add_cpu
(
&
agi
->
agi_freecount
,
-
1
);
xfs_ialloc_log_agi
(
tp
,
agbp
,
XFS_AGI_FREECOUNT
);
down_read
(
&
mp
->
m_peraglock
);
mp
->
m_perag
[
tagno
].
pagi_freecount
--
;
up_read
(
&
mp
->
m_peraglock
);
#ifdef DEBUG
if
(
cur
->
bc_nlevels
==
1
)
{
int
freecount
=
0
;
if
((
error
=
xfs_inobt_lookup_ge
(
cur
,
0
,
0
,
0
,
&
i
)))
goto
error0
;
do
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error0
;
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
freecount
+=
rec
.
ir_freecount
;
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error0
;
}
while
(
i
==
1
);
ASSERT
(
freecount
==
be32_to_cpu
(
agi
->
agi_freecount
)
||
XFS_FORCED_SHUTDOWN
(
mp
));
}
#endif
error
=
xfs_check_agi_freecount
(
cur
,
agi
);
if
(
error
)
goto
error0
;
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
xfs_trans_mod_sb
(
tp
,
XFS_TRANS_SB_IFREE
,
-
1
);
*
inop
=
ino
;
...
...
@@ -1062,38 +1103,23 @@ xfs_difree(
* Initialize the cursor.
*/
cur
=
xfs_inobt_init_cursor
(
mp
,
tp
,
agbp
,
agno
);
#ifdef DEBUG
if
(
cur
->
bc_nlevels
==
1
)
{
int
freecount
=
0
;
if
((
error
=
xfs_inobt_lookup_ge
(
cur
,
0
,
0
,
0
,
&
i
)))
goto
error0
;
do
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error0
;
if
(
i
)
{
freecount
+=
rec
.
ir_freecount
;
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error0
;
}
}
while
(
i
==
1
);
ASSERT
(
freecount
==
be32_to_cpu
(
agi
->
agi_freecount
)
||
XFS_FORCED_SHUTDOWN
(
mp
));
}
#endif
error
=
xfs_check_agi_freecount
(
cur
,
agi
);
if
(
error
)
goto
error0
;
/*
* Look for the entry describing this inode.
*/
if
((
error
=
xfs_inobt_lookup
_le
(
cur
,
agino
,
0
,
0
,
&
i
)))
{
if
((
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_LE
,
&
i
)))
{
cmn_err
(
CE_WARN
,
"xfs_difree: xfs_inobt_lookup
_le
returned() an error %d on %s. Returning error."
,
"xfs_difree: xfs_inobt_lookup returned() an error %d on %s. Returning error."
,
error
,
mp
->
m_fsname
);
goto
error0
;
}
XFS_WANT_CORRUPTED_GOTO
(
i
==
1
,
error0
);
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
))
)
{
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
,
&
i
);
if
(
error
)
{
cmn_err
(
CE_WARN
,
"xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error."
,
error
,
mp
->
m_fsname
);
...
...
@@ -1148,12 +1174,14 @@ xfs_difree(
}
else
{
*
delete
=
0
;
if
((
error
=
xfs_inobt_update
(
cur
,
rec
.
ir_startino
,
rec
.
ir_freecount
,
rec
.
ir_free
)))
{
error
=
xfs_inobt_update
(
cur
,
&
rec
);
if
(
error
)
{
cmn_err
(
CE_WARN
,
"xfs_difree: xfs_inobt_update() returned an error %d on %s. Returning error
."
,
"xfs_difree: xfs_inobt_update returned an error %d on %s
."
,
error
,
mp
->
m_fsname
);
goto
error0
;
}
/*
* Change the inode free counts and log the ag/sb changes.
*/
...
...
@@ -1165,28 +1193,10 @@ xfs_difree(
xfs_trans_mod_sb
(
tp
,
XFS_TRANS_SB_IFREE
,
1
);
}
#ifdef DEBUG
if
(
cur
->
bc_nlevels
==
1
)
{
int
freecount
=
0
;
error
=
xfs_check_agi_freecount
(
cur
,
agi
);
if
(
error
)
goto
error
0
;
if
((
error
=
xfs_inobt_lookup_ge
(
cur
,
0
,
0
,
0
,
&
i
)))
goto
error0
;
do
{
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
rec
.
ir_startino
,
&
rec
.
ir_freecount
,
&
rec
.
ir_free
,
&
i
)))
goto
error0
;
if
(
i
)
{
freecount
+=
rec
.
ir_freecount
;
if
((
error
=
xfs_btree_increment
(
cur
,
0
,
&
i
)))
goto
error0
;
}
}
while
(
i
==
1
);
ASSERT
(
freecount
==
be32_to_cpu
(
agi
->
agi_freecount
)
||
XFS_FORCED_SHUTDOWN
(
mp
));
}
#endif
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
return
0
;
...
...
@@ -1297,9 +1307,7 @@ xfs_imap(
chunk_agbno
=
agbno
-
offset_agbno
;
}
else
{
xfs_btree_cur_t
*
cur
;
/* inode btree cursor */
xfs_agino_t
chunk_agino
;
/* first agino in inode chunk */
__int32_t
chunk_cnt
;
/* count of free inodes in chunk */
xfs_inofree_t
chunk_free
;
/* mask of free inodes in chunk */
xfs_inobt_rec_incore_t
chunk_rec
;
xfs_buf_t
*
agbp
;
/* agi buffer */
int
i
;
/* temp state */
...
...
@@ -1315,15 +1323,14 @@ xfs_imap(
}
cur
=
xfs_inobt_init_cursor
(
mp
,
tp
,
agbp
,
agno
);
error
=
xfs_inobt_lookup
_le
(
cur
,
agino
,
0
,
0
,
&
i
);
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_LE
,
&
i
);
if
(
error
)
{
xfs_fs_cmn_err
(
CE_ALERT
,
mp
,
"xfs_imap: "
"xfs_inobt_lookup
_le
() failed"
);
"xfs_inobt_lookup() failed"
);
goto
error0
;
}
error
=
xfs_inobt_get_rec
(
cur
,
&
chunk_agino
,
&
chunk_cnt
,
&
chunk_free
,
&
i
);
error
=
xfs_inobt_get_rec
(
cur
,
&
chunk_rec
,
&
i
);
if
(
error
)
{
xfs_fs_cmn_err
(
CE_ALERT
,
mp
,
"xfs_imap: "
"xfs_inobt_get_rec() failed"
);
...
...
@@ -1341,7 +1348,7 @@ xfs_imap(
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
if
(
error
)
return
error
;
chunk_agbno
=
XFS_AGINO_TO_AGBNO
(
mp
,
chunk_
ag
ino
);
chunk_agbno
=
XFS_AGINO_TO_AGBNO
(
mp
,
chunk_
rec
.
ir_start
ino
);
offset_agbno
=
agbno
-
chunk_agbno
;
}
...
...
fs/xfs/xfs_ialloc.h
View file @
fdec29c5
...
...
@@ -150,23 +150,15 @@ xfs_ialloc_pagi_init(
xfs_agnumber_t
agno
);
/* allocation group number */
/*
* Lookup the first record greater than or equal to ino
* in the btree given by cur.
* Lookup a record by ino in the btree given by cur.
*/
int
xfs_inobt_lookup_ge
(
struct
xfs_btree_cur
*
cur
,
xfs_agino_t
ino
,
__int32_t
fcnt
,
xfs_inofree_t
free
,
int
*
stat
);
/*
* Lookup the first record less than or equal to ino
* in the btree given by cur.
*/
int
xfs_inobt_lookup_le
(
struct
xfs_btree_cur
*
cur
,
xfs_agino_t
ino
,
__int32_t
fcnt
,
xfs_inofree_t
free
,
int
*
stat
);
int
xfs_inobt_lookup
(
struct
xfs_btree_cur
*
cur
,
xfs_agino_t
ino
,
xfs_lookup_t
dir
,
int
*
stat
);
/*
* Get the data from the pointed-to record.
*/
extern
int
xfs_inobt_get_rec
(
struct
xfs_btree_cur
*
cur
,
xfs_agino_t
*
ino
,
__int32_t
*
fcnt
,
xfs_inofree_t
*
free
,
int
*
stat
);
extern
int
xfs_inobt_get_rec
(
struct
xfs_btree_cur
*
cur
,
xfs_inobt_rec_incore_t
*
rec
,
int
*
stat
);
#endif
/* __XFS_IALLOC_H__ */
fs/xfs/xfs_iget.c
View file @
fdec29c5
...
...
@@ -82,7 +82,6 @@ xfs_inode_alloc(
memset
(
&
ip
->
i_df
,
0
,
sizeof
(
xfs_ifork_t
));
ip
->
i_flags
=
0
;
ip
->
i_update_core
=
0
;
ip
->
i_update_size
=
0
;
ip
->
i_delayed_blks
=
0
;
memset
(
&
ip
->
i_d
,
0
,
sizeof
(
xfs_icdinode_t
));
ip
->
i_size
=
0
;
...
...
@@ -456,32 +455,6 @@ xfs_iget(
return
error
;
}
/*
* Look for the inode corresponding to the given ino in the hash table.
* If it is there and its i_transp pointer matches tp, return it.
* Otherwise, return NULL.
*/
xfs_inode_t
*
xfs_inode_incore
(
xfs_mount_t
*
mp
,
xfs_ino_t
ino
,
xfs_trans_t
*
tp
)
{
xfs_inode_t
*
ip
;
xfs_perag_t
*
pag
;
pag
=
xfs_get_perag
(
mp
,
ino
);
read_lock
(
&
pag
->
pag_ici_lock
);
ip
=
radix_tree_lookup
(
&
pag
->
pag_ici_root
,
XFS_INO_TO_AGINO
(
mp
,
ino
));
read_unlock
(
&
pag
->
pag_ici_lock
);
xfs_put_perag
(
mp
,
pag
);
/* the returned inode must match the transaction */
if
(
ip
&&
(
ip
->
i_transp
!=
tp
))
return
NULL
;
return
ip
;
}
/*
* Decrement reference count of an inode structure and unlock it.
*
...
...
fs/xfs/xfs_inode.c
View file @
fdec29c5
...
...
@@ -651,7 +651,7 @@ xfs_iformat_btree(
return
0
;
}
void
STATIC
void
xfs_dinode_from_disk
(
xfs_icdinode_t
*
to
,
xfs_dinode_t
*
from
)
...
...
@@ -1247,7 +1247,7 @@ xfs_isize_check(
* In that case the pages will still be in memory, but the inode size
* will never have been updated.
*/
xfs_fsize_t
STATIC
xfs_fsize_t
xfs_file_last_byte
(
xfs_inode_t
*
ip
)
{
...
...
@@ -3837,7 +3837,7 @@ xfs_iext_inline_to_direct(
/*
* Resize an extent indirection array to new_size bytes.
*/
void
STATIC
void
xfs_iext_realloc_indirect
(
xfs_ifork_t
*
ifp
,
/* inode fork pointer */
int
new_size
)
/* new indirection array size */
...
...
@@ -3862,7 +3862,7 @@ xfs_iext_realloc_indirect(
/*
* Switch from indirection array to linear (direct) extent allocations.
*/
void
STATIC
void
xfs_iext_indirect_to_direct
(
xfs_ifork_t
*
ifp
)
/* inode fork pointer */
{
...
...
fs/xfs/xfs_inode.h
View file @
fdec29c5
...
...
@@ -261,7 +261,6 @@ typedef struct xfs_inode {
/* Miscellaneous state. */
unsigned
short
i_flags
;
/* see defined flags below */
unsigned
char
i_update_core
;
/* timestamps/size is dirty */
unsigned
char
i_update_size
;
/* di_size field is dirty */
unsigned
int
i_delayed_blks
;
/* count of delay alloc blks */
xfs_icdinode_t
i_d
;
/* most of ondisk inode */
...
...
@@ -468,8 +467,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
/*
* xfs_iget.c prototypes.
*/
xfs_inode_t
*
xfs_inode_incore
(
struct
xfs_mount
*
,
xfs_ino_t
,
struct
xfs_trans
*
);
int
xfs_iget
(
struct
xfs_mount
*
,
struct
xfs_trans
*
,
xfs_ino_t
,
uint
,
uint
,
xfs_inode_t
**
,
xfs_daddr_t
);
void
xfs_iput
(
xfs_inode_t
*
,
uint
);
...
...
@@ -504,7 +501,6 @@ void xfs_ipin(xfs_inode_t *);
void
xfs_iunpin
(
xfs_inode_t
*
);
int
xfs_iflush
(
xfs_inode_t
*
,
uint
);
void
xfs_ichgtime
(
xfs_inode_t
*
,
int
);
xfs_fsize_t
xfs_file_last_byte
(
xfs_inode_t
*
);
void
xfs_lock_inodes
(
xfs_inode_t
**
,
int
,
uint
);
void
xfs_lock_two_inodes
(
xfs_inode_t
*
,
xfs_inode_t
*
,
uint
);
...
...
@@ -572,8 +568,6 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
struct
xfs_buf
**
,
uint
);
int
xfs_iread
(
struct
xfs_mount
*
,
struct
xfs_trans
*
,
struct
xfs_inode
*
,
xfs_daddr_t
,
uint
);
void
xfs_dinode_from_disk
(
struct
xfs_icdinode
*
,
struct
xfs_dinode
*
);
void
xfs_dinode_to_disk
(
struct
xfs_dinode
*
,
struct
xfs_icdinode
*
);
void
xfs_idestroy_fork
(
struct
xfs_inode
*
,
int
);
...
...
@@ -592,8 +586,6 @@ void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
void
xfs_iext_remove_direct
(
xfs_ifork_t
*
,
xfs_extnum_t
,
int
);
void
xfs_iext_remove_indirect
(
xfs_ifork_t
*
,
xfs_extnum_t
,
int
);
void
xfs_iext_realloc_direct
(
xfs_ifork_t
*
,
int
);
void
xfs_iext_realloc_indirect
(
xfs_ifork_t
*
,
int
);
void
xfs_iext_indirect_to_direct
(
xfs_ifork_t
*
);
void
xfs_iext_direct_to_inline
(
xfs_ifork_t
*
,
xfs_extnum_t
);
void
xfs_iext_inline_to_direct
(
xfs_ifork_t
*
,
int
);
void
xfs_iext_destroy
(
xfs_ifork_t
*
);
...
...
fs/xfs/xfs_inode_item.c
View file @
fdec29c5
...
...
@@ -262,14 +262,6 @@ xfs_inode_item_format(
SYNCHRONIZE
();
}
/*
* We don't have to worry about re-ordering here because
* the update_size field is protected by the inode lock
* and we have that held in exclusive mode.
*/
if
(
ip
->
i_update_size
)
ip
->
i_update_size
=
0
;
/*
* Make sure to get the latest atime from the Linux inode.
*/
...
...
@@ -712,8 +704,6 @@ xfs_inode_item_unlock(
* Clear out the fields of the inode log item particular
* to the current transaction.
*/
iip
->
ili_ilock_recur
=
0
;
iip
->
ili_iolock_recur
=
0
;
iip
->
ili_flags
=
0
;
/*
...
...
fs/xfs/xfs_inode_item.h
View file @
fdec29c5
...
...
@@ -137,8 +137,6 @@ typedef struct xfs_inode_log_item {
struct
xfs_inode
*
ili_inode
;
/* inode ptr */
xfs_lsn_t
ili_flush_lsn
;
/* lsn at last flush */
xfs_lsn_t
ili_last_lsn
;
/* lsn at last transaction */
unsigned
short
ili_ilock_recur
;
/* lock recursion count */
unsigned
short
ili_iolock_recur
;
/* lock recursion count */
unsigned
short
ili_flags
;
/* misc flags */
unsigned
short
ili_logged
;
/* flushed logged data */
unsigned
int
ili_last_fields
;
/* fields when flushed */
...
...
fs/xfs/xfs_inum.h
View file @
fdec29c5
...
...
@@ -72,7 +72,6 @@ struct xfs_mount;
#if XFS_BIG_INUMS
#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL))
#define XFS_INO64_OFFSET ((xfs_ino_t)(1ULL << 32))
#else
#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 32) - 1ULL))
#endif
...
...
fs/xfs/xfs_itable.c
View file @
fdec29c5
...
...
@@ -39,7 +39,7 @@
#include "xfs_error.h"
#include "xfs_btree.h"
int
STATIC
int
xfs_internal_inum
(
xfs_mount_t
*
mp
,
xfs_ino_t
ino
)
...
...
@@ -353,9 +353,6 @@ xfs_bulkstat(
int
end_of_ag
;
/* set if we've seen the ag end */
int
error
;
/* error code */
int
fmterror
;
/* bulkstat formatter result */
__int32_t
gcnt
;
/* current btree rec's count */
xfs_inofree_t
gfree
;
/* current btree rec's free mask */
xfs_agino_t
gino
;
/* current btree rec's start inode */
int
i
;
/* loop index */
int
icount
;
/* count of inodes good in irbuf */
size_t
irbsize
;
/* size of irec buffer in bytes */
...
...
@@ -442,40 +439,43 @@ xfs_bulkstat(
* we need to get the remainder of the chunk we're in.
*/
if
(
agino
>
0
)
{
xfs_inobt_rec_incore_t
r
;
/*
* Lookup the inode chunk that this inode lives in.
*/
error
=
xfs_inobt_lookup_le
(
cur
,
agino
,
0
,
0
,
&
tmp
);
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_LE
,
&
tmp
);
if
(
!
error
&&
/* no I/O error */
tmp
&&
/* lookup succeeded */
/* got the record, should always work */
!
(
error
=
xfs_inobt_get_rec
(
cur
,
&
gino
,
&
gcnt
,
&
gfree
,
&
i
))
&&
!
(
error
=
xfs_inobt_get_rec
(
cur
,
&
r
,
&
i
))
&&
i
==
1
&&
/* this is the right chunk */
agino
<
g
ino
+
XFS_INODES_PER_CHUNK
&&
agino
<
r
.
ir_start
ino
+
XFS_INODES_PER_CHUNK
&&
/* lastino was not last in chunk */
(
chunkidx
=
agino
-
g
ino
+
1
)
<
(
chunkidx
=
agino
-
r
.
ir_start
ino
+
1
)
<
XFS_INODES_PER_CHUNK
&&
/* there are some left allocated */
xfs_inobt_maskn
(
chunkidx
,
XFS_INODES_PER_CHUNK
-
chunkidx
)
&
~
gfree
)
{
XFS_INODES_PER_CHUNK
-
chunkidx
)
&
~
r
.
ir_free
)
{
/*
* Grab the chunk record. Mark all the
* uninteresting inodes (because they're
* before our start point) free.
*/
for
(
i
=
0
;
i
<
chunkidx
;
i
++
)
{
if
(
XFS_INOBT_MASK
(
i
)
&
~
g
free
)
gc
nt
++
;
if
(
XFS_INOBT_MASK
(
i
)
&
~
r
.
ir_
free
)
r
.
ir_freecou
nt
++
;
}
g
free
|=
xfs_inobt_maskn
(
0
,
chunkidx
);
irbp
->
ir_startino
=
g
ino
;
irbp
->
ir_freecount
=
gc
nt
;
irbp
->
ir_free
=
g
free
;
r
.
ir_
free
|=
xfs_inobt_maskn
(
0
,
chunkidx
);
irbp
->
ir_startino
=
r
.
ir_start
ino
;
irbp
->
ir_freecount
=
r
.
ir_freecou
nt
;
irbp
->
ir_free
=
r
.
ir_
free
;
irbp
++
;
agino
=
g
ino
+
XFS_INODES_PER_CHUNK
;
icount
=
XFS_INODES_PER_CHUNK
-
gc
nt
;
agino
=
r
.
ir_start
ino
+
XFS_INODES_PER_CHUNK
;
icount
=
XFS_INODES_PER_CHUNK
-
r
.
ir_freecou
nt
;
}
else
{
/*
* If any of those tests failed, bump the
...
...
@@ -493,7 +493,7 @@ xfs_bulkstat(
/*
* Start of ag. Lookup the first inode chunk.
*/
error
=
xfs_inobt_lookup
_ge
(
cur
,
0
,
0
,
0
,
&
tmp
);
error
=
xfs_inobt_lookup
(
cur
,
0
,
XFS_LOOKUP_GE
,
&
tmp
);
icount
=
0
;
}
/*
...
...
@@ -501,6 +501,8 @@ xfs_bulkstat(
* until we run out of inodes or space in the buffer.
*/
while
(
irbp
<
irbufend
&&
icount
<
ubcount
)
{
xfs_inobt_rec_incore_t
r
;
/*
* Loop as long as we're unable to read the
* inode btree.
...
...
@@ -510,51 +512,55 @@ xfs_bulkstat(
if
(
XFS_AGINO_TO_AGBNO
(
mp
,
agino
)
>=
be32_to_cpu
(
agi
->
agi_length
))
break
;
error
=
xfs_inobt_lookup
_ge
(
cur
,
agino
,
0
,
0
,
&
tmp
);
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_GE
,
&
tmp
);
cond_resched
();
}
/*
* If ran off the end of the ag either with an error,
* or the normal way, set end and stop collecting.
*/
if
(
error
||
(
error
=
xfs_inobt_get_rec
(
cur
,
&
gino
,
&
gcnt
,
&
gfree
,
&
i
))
||
i
==
0
)
{
if
(
error
)
{
end_of_ag
=
1
;
break
;
}
error
=
xfs_inobt_get_rec
(
cur
,
&
r
,
&
i
);
if
(
error
||
i
==
0
)
{
end_of_ag
=
1
;
break
;
}
/*
* If this chunk has any allocated inodes, save it.
* Also start read-ahead now for this chunk.
*/
if
(
gc
nt
<
XFS_INODES_PER_CHUNK
)
{
if
(
r
.
ir_freecou
nt
<
XFS_INODES_PER_CHUNK
)
{
/*
* Loop over all clusters in the next chunk.
* Do a readahead if there are any allocated
* inodes in that cluster.
*/
for
(
agbno
=
XFS_AGINO_TO_AGBNO
(
mp
,
gino
),
chunkidx
=
0
;
agbno
=
XFS_AGINO_TO_AGBNO
(
mp
,
r
.
ir_startino
);
for
(
chunkidx
=
0
;
chunkidx
<
XFS_INODES_PER_CHUNK
;
chunkidx
+=
nicluster
,
agbno
+=
nbcluster
)
{
if
(
xfs_inobt_maskn
(
chunkidx
,
nicluster
)
&
~
g
free
)
if
(
xfs_inobt_maskn
(
chunkidx
,
nicluster
)
&
~
r
.
ir_
free
)
xfs_btree_reada_bufs
(
mp
,
agno
,
agbno
,
nbcluster
);
}
irbp
->
ir_startino
=
g
ino
;
irbp
->
ir_freecount
=
gc
nt
;
irbp
->
ir_free
=
g
free
;
irbp
->
ir_startino
=
r
.
ir_start
ino
;
irbp
->
ir_freecount
=
r
.
ir_freecou
nt
;
irbp
->
ir_free
=
r
.
ir_
free
;
irbp
++
;
icount
+=
XFS_INODES_PER_CHUNK
-
gc
nt
;
icount
+=
XFS_INODES_PER_CHUNK
-
r
.
ir_freecou
nt
;
}
/*
* Set agino to after this chunk and bump the cursor.
*/
agino
=
g
ino
+
XFS_INODES_PER_CHUNK
;
agino
=
r
.
ir_start
ino
+
XFS_INODES_PER_CHUNK
;
error
=
xfs_btree_increment
(
cur
,
0
,
&
tmp
);
cond_resched
();
}
...
...
@@ -820,9 +826,7 @@ xfs_inumbers(
int
bufidx
;
xfs_btree_cur_t
*
cur
;
int
error
;
__int32_t
gcnt
;
xfs_inofree_t
gfree
;
xfs_agino_t
gino
;
xfs_inobt_rec_incore_t
r
;
int
i
;
xfs_ino_t
ino
;
int
left
;
...
...
@@ -855,7 +859,8 @@ xfs_inumbers(
continue
;
}
cur
=
xfs_inobt_init_cursor
(
mp
,
NULL
,
agbp
,
agno
);
error
=
xfs_inobt_lookup_ge
(
cur
,
agino
,
0
,
0
,
&
tmp
);
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_GE
,
&
tmp
);
if
(
error
)
{
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_ERROR
);
cur
=
NULL
;
...
...
@@ -870,9 +875,8 @@ xfs_inumbers(
continue
;
}
}
if
((
error
=
xfs_inobt_get_rec
(
cur
,
&
gino
,
&
gcnt
,
&
gfree
,
&
i
))
||
i
==
0
)
{
error
=
xfs_inobt_get_rec
(
cur
,
&
r
,
&
i
);
if
(
error
||
i
==
0
)
{
xfs_buf_relse
(
agbp
);
agbp
=
NULL
;
xfs_btree_del_cursor
(
cur
,
XFS_BTREE_NOERROR
);
...
...
@@ -881,10 +885,12 @@ xfs_inumbers(
agino
=
0
;
continue
;
}
agino
=
gino
+
XFS_INODES_PER_CHUNK
-
1
;
buffer
[
bufidx
].
xi_startino
=
XFS_AGINO_TO_INO
(
mp
,
agno
,
gino
);
buffer
[
bufidx
].
xi_alloccount
=
XFS_INODES_PER_CHUNK
-
gcnt
;
buffer
[
bufidx
].
xi_allocmask
=
~
gfree
;
agino
=
r
.
ir_startino
+
XFS_INODES_PER_CHUNK
-
1
;
buffer
[
bufidx
].
xi_startino
=
XFS_AGINO_TO_INO
(
mp
,
agno
,
r
.
ir_startino
);
buffer
[
bufidx
].
xi_alloccount
=
XFS_INODES_PER_CHUNK
-
r
.
ir_freecount
;
buffer
[
bufidx
].
xi_allocmask
=
~
r
.
ir_free
;
bufidx
++
;
left
--
;
if
(
bufidx
==
bcount
)
{
...
...
fs/xfs/xfs_itable.h
View file @
fdec29c5
...
...
@@ -99,11 +99,6 @@ xfs_bulkstat_one(
void
*
dibuff
,
int
*
stat
);
int
xfs_internal_inum
(
xfs_mount_t
*
mp
,
xfs_ino_t
ino
);
typedef
int
(
*
inumbers_fmt_pf
)(
void
__user
*
ubuffer
,
/* buffer to write to */
const
xfs_inogrp_t
*
buffer
,
/* buffer to read from */
...
...
fs/xfs/xfs_log_priv.h
View file @
fdec29c5
...
...
@@ -451,8 +451,6 @@ extern int xlog_find_tail(xlog_t *log,
extern
int
xlog_recover
(
xlog_t
*
log
);
extern
int
xlog_recover_finish
(
xlog_t
*
log
);
extern
void
xlog_pack_data
(
xlog_t
*
log
,
xlog_in_core_t
*
iclog
,
int
);
extern
void
xlog_recover_process_iunlinks
(
xlog_t
*
log
);
extern
struct
xfs_buf
*
xlog_get_bp
(
xlog_t
*
,
int
);
extern
void
xlog_put_bp
(
struct
xfs_buf
*
);
...
...
fs/xfs/xfs_log_recover.c
View file @
fdec29c5
...
...
@@ -3263,7 +3263,7 @@ xlog_recover_process_one_iunlink(
* freeing of the inode and its removal from the list must be
* atomic.
*/
void
STATIC
void
xlog_recover_process_iunlinks
(
xlog_t
*
log
)
{
...
...
fs/xfs/xfs_mount.c
View file @
fdec29c5
...
...
@@ -1568,7 +1568,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
*
* The m_sb_lock must be held when this routine is called.
*/
int
STATIC
int
xfs_mod_incore_sb_unlocked
(
xfs_mount_t
*
mp
,
xfs_sb_field_t
field
,
...
...
fs/xfs/xfs_mount.h
View file @
fdec29c5
...
...
@@ -414,13 +414,10 @@ typedef struct xfs_mod_sb {
extern
int
xfs_log_sbcount
(
xfs_mount_t
*
,
uint
);
extern
int
xfs_mountfs
(
xfs_mount_t
*
mp
);
extern
void
xfs_mountfs_check_barriers
(
xfs_mount_t
*
mp
);
extern
void
xfs_unmountfs
(
xfs_mount_t
*
);
extern
int
xfs_unmountfs_writesb
(
xfs_mount_t
*
);
extern
int
xfs_mod_incore_sb
(
xfs_mount_t
*
,
xfs_sb_field_t
,
int64_t
,
int
);
extern
int
xfs_mod_incore_sb_unlocked
(
xfs_mount_t
*
,
xfs_sb_field_t
,
int64_t
,
int
);
extern
int
xfs_mod_incore_sb_batch
(
xfs_mount_t
*
,
xfs_mod_sb_t
*
,
uint
,
int
);
extern
int
xfs_mount_log_sb
(
xfs_mount_t
*
,
__int64_t
);
...
...
fs/xfs/xfs_mru_cache.c
View file @
fdec29c5
...
...
@@ -563,35 +563,6 @@ xfs_mru_cache_lookup(
return
elem
?
elem
->
value
:
NULL
;
}
/*
* To look up an element using its key, but leave its location in the internal
* lists alone, call xfs_mru_cache_peek(). If the element isn't found, this
* function returns NULL.
*
* See the comments above the declaration of the xfs_mru_cache_lookup() function
* for important locking information pertaining to this call.
*/
void
*
xfs_mru_cache_peek
(
xfs_mru_cache_t
*
mru
,
unsigned
long
key
)
{
xfs_mru_cache_elem_t
*
elem
;
ASSERT
(
mru
&&
mru
->
lists
);
if
(
!
mru
||
!
mru
->
lists
)
return
NULL
;
spin_lock
(
&
mru
->
lock
);
elem
=
radix_tree_lookup
(
&
mru
->
store
,
key
);
if
(
!
elem
)
spin_unlock
(
&
mru
->
lock
);
else
__release
(
mru_lock
);
/* help sparse not be stupid */
return
elem
?
elem
->
value
:
NULL
;
}
/*
* To release the internal data structure spinlock after having performed an
* xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done()
...
...
fs/xfs/xfs_mru_cache.h
View file @
fdec29c5
...
...
@@ -49,7 +49,6 @@ int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key,
void
*
xfs_mru_cache_remove
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
xfs_mru_cache_delete
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
*
xfs_mru_cache_lookup
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
*
xfs_mru_cache_peek
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
xfs_mru_cache_done
(
struct
xfs_mru_cache
*
mru
);
#endif
/* __XFS_MRU_CACHE_H__ */
fs/xfs/xfs_rw.c
View file @
fdec29c5
...
...
@@ -87,90 +87,6 @@ xfs_write_clear_setuid(
return
0
;
}
/*
* Handle logging requirements of various synchronous types of write.
*/
int
xfs_write_sync_logforce
(
xfs_mount_t
*
mp
,
xfs_inode_t
*
ip
)
{
int
error
=
0
;
/*
* If we're treating this as O_DSYNC and we have not updated the
* size, force the log.
*/
if
(
!
(
mp
->
m_flags
&
XFS_MOUNT_OSYNCISOSYNC
)
&&
!
(
ip
->
i_update_size
))
{
xfs_inode_log_item_t
*
iip
=
ip
->
i_itemp
;
/*
* If an allocation transaction occurred
* without extending the size, then we have to force
* the log up the proper point to ensure that the
* allocation is permanent. We can't count on
* the fact that buffered writes lock out direct I/O
* writes - the direct I/O write could have extended
* the size nontransactionally, then finished before
* we started. xfs_write_file will think that the file
* didn't grow but the update isn't safe unless the
* size change is logged.
*
* Force the log if we've committed a transaction
* against the inode or if someone else has and
* the commit record hasn't gone to disk (e.g.
* the inode is pinned). This guarantees that
* all changes affecting the inode are permanent
* when we return.
*/
if
(
iip
&&
iip
->
ili_last_lsn
)
{
error
=
_xfs_log_force
(
mp
,
iip
->
ili_last_lsn
,
XFS_LOG_FORCE
|
XFS_LOG_SYNC
,
NULL
);
}
else
if
(
xfs_ipincount
(
ip
)
>
0
)
{
error
=
_xfs_log_force
(
mp
,
(
xfs_lsn_t
)
0
,
XFS_LOG_FORCE
|
XFS_LOG_SYNC
,
NULL
);
}
}
else
{
xfs_trans_t
*
tp
;
/*
* O_SYNC or O_DSYNC _with_ a size update are handled
* the same way.
*
* If the write was synchronous then we need to make
* sure that the inode modification time is permanent.
* We'll have updated the timestamp above, so here
* we use a synchronous transaction to log the inode.
* It's not fast, but it's necessary.
*
* If this a dsync write and the size got changed
* non-transactionally, then we need to ensure that
* the size change gets logged in a synchronous
* transaction.
*/
tp
=
xfs_trans_alloc
(
mp
,
XFS_TRANS_WRITE_SYNC
);
if
((
error
=
xfs_trans_reserve
(
tp
,
0
,
XFS_SWRITE_LOG_RES
(
mp
),
0
,
0
,
0
)))
{
/* Transaction reserve failed */
xfs_trans_cancel
(
tp
,
0
);
}
else
{
/* Transaction reserve successful */
xfs_ilock
(
ip
,
XFS_ILOCK_EXCL
);
xfs_trans_ijoin
(
tp
,
ip
,
XFS_ILOCK_EXCL
);
xfs_trans_ihold
(
tp
,
ip
);
xfs_trans_log_inode
(
tp
,
ip
,
XFS_ILOG_CORE
);
xfs_trans_set_sync
(
tp
);
error
=
xfs_trans_commit
(
tp
,
0
);
xfs_iunlock
(
ip
,
XFS_ILOCK_EXCL
);
}
}
return
error
;
}
/*
* Force a shutdown of the filesystem instantly while keeping
* the filesystem consistent. We don't do an unmount here; just shutdown
...
...
fs/xfs/xfs_rw.h
View file @
fdec29c5
...
...
@@ -68,7 +68,6 @@ xfs_get_extsz_hint(
* Prototypes for functions in xfs_rw.c.
*/
extern
int
xfs_write_clear_setuid
(
struct
xfs_inode
*
ip
);
extern
int
xfs_write_sync_logforce
(
struct
xfs_mount
*
mp
,
struct
xfs_inode
*
ip
);
extern
int
xfs_bwrite
(
struct
xfs_mount
*
mp
,
struct
xfs_buf
*
bp
);
extern
int
xfs_bioerror
(
struct
xfs_buf
*
bp
);
extern
int
xfs_bioerror_relse
(
struct
xfs_buf
*
bp
);
...
...
@@ -78,10 +77,4 @@ extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp,
extern
void
xfs_ioerror_alert
(
char
*
func
,
struct
xfs_mount
*
mp
,
xfs_buf_t
*
bp
,
xfs_daddr_t
blkno
);
/*
* Prototypes for functions in xfs_vnodeops.c.
*/
extern
int
xfs_free_eofblocks
(
struct
xfs_mount
*
mp
,
struct
xfs_inode
*
ip
,
int
flags
);
#endif
/* __XFS_RW_H__ */
fs/xfs/xfs_trans.h
View file @
fdec29c5
...
...
@@ -68,7 +68,7 @@ typedef struct xfs_trans_header {
#define XFS_TRANS_GROWFS 14
#define XFS_TRANS_STRAT_WRITE 15
#define XFS_TRANS_DIOSTRAT 16
#define XFS_TRANS_WRITE_SYNC 17
/* 17 was XFS_TRANS_WRITE_SYNC */
#define XFS_TRANS_WRITEID 18
#define XFS_TRANS_ADDAFORK 19
#define XFS_TRANS_ATTRINVAL 20
...
...
fs/xfs/xfs_trans_buf.c
View file @
fdec29c5
...
...
@@ -307,7 +307,7 @@ xfs_trans_read_buf(
return
(
flags
&
XFS_BUF_TRYLOCK
)
?
EAGAIN
:
XFS_ERROR
(
ENOMEM
);
if
(
(
bp
!=
NULL
)
&&
(
XFS_BUF_GETERROR
(
bp
)
!=
0
)
)
{
if
(
XFS_BUF_GETERROR
(
bp
)
!=
0
)
{
xfs_ioerror_alert
(
"xfs_trans_read_buf"
,
mp
,
bp
,
blkno
);
error
=
XFS_BUF_GETERROR
(
bp
);
...
...
@@ -315,7 +315,7 @@ xfs_trans_read_buf(
return
error
;
}
#ifdef DEBUG
if
(
xfs_do_error
&&
(
bp
!=
NULL
)
)
{
if
(
xfs_do_error
)
{
if
(
xfs_error_target
==
target
)
{
if
(((
xfs_req_num
++
)
%
xfs_error_mod
)
==
0
)
{
xfs_buf_relse
(
bp
);
...
...
fs/xfs/xfs_trans_inode.c
View file @
fdec29c5
...
...
@@ -49,30 +49,7 @@ xfs_trans_inode_broot_debug(
/*
* Get and lock the inode for the caller if it is not already
* locked within the given transaction. If it is already locked
* within the transaction, just increment its lock recursion count
* and return a pointer to it.
*
* For an inode to be locked in a transaction, the inode lock, as
* opposed to the io lock, must be taken exclusively. This ensures
* that the inode can be involved in only 1 transaction at a time.
* Lock recursion is handled on the io lock, but only for lock modes
* of equal or lesser strength. That is, you can recur on the io lock
* held EXCL with a SHARED request but not vice versa. Also, if
* the inode is already a part of the transaction then you cannot
* go from not holding the io lock to having it EXCL or SHARED.
*
* Use the inode cache routine xfs_inode_incore() to find the inode
* if it is already owned by this transaction.
*
* If we don't already own the inode, use xfs_iget() to get it.
* Since the inode log item structure is embedded in the incore
* inode structure and is initialized when the inode is brought
* into memory, there is nothing to do with it here.
*
* If the given transaction pointer is NULL, just call xfs_iget().
* This simplifies code which must handle both cases.
* Get an inode and join it to the transaction.
*/
int
xfs_trans_iget
(
...
...
@@ -84,62 +61,11 @@ xfs_trans_iget(
xfs_inode_t
**
ipp
)
{
int
error
;
xfs_inode_t
*
ip
;
/*
* If the transaction pointer is NULL, just call the normal
* xfs_iget().
*/
if
(
tp
==
NULL
)
return
xfs_iget
(
mp
,
NULL
,
ino
,
flags
,
lock_flags
,
ipp
,
0
);
/*
* If we find the inode in core with this transaction
* pointer in its i_transp field, then we know we already
* have it locked. In this case we just increment the lock
* recursion count and return the inode to the caller.
* Assert that the inode is already locked in the mode requested
* by the caller. We cannot do lock promotions yet, so
* die if someone gets this wrong.
*/
if
((
ip
=
xfs_inode_incore
(
tp
->
t_mountp
,
ino
,
tp
))
!=
NULL
)
{
/*
* Make sure that the inode lock is held EXCL and
* that the io lock is never upgraded when the inode
* is already a part of the transaction.
*/
ASSERT
(
ip
->
i_itemp
!=
NULL
);
ASSERT
(
lock_flags
&
XFS_ILOCK_EXCL
);
ASSERT
(
xfs_isilocked
(
ip
,
XFS_ILOCK_EXCL
));
ASSERT
((
!
(
lock_flags
&
XFS_IOLOCK_EXCL
))
||
xfs_isilocked
(
ip
,
XFS_IOLOCK_EXCL
));
ASSERT
((
!
(
lock_flags
&
XFS_IOLOCK_EXCL
))
||
(
ip
->
i_itemp
->
ili_flags
&
XFS_ILI_IOLOCKED_EXCL
));
ASSERT
((
!
(
lock_flags
&
XFS_IOLOCK_SHARED
))
||
xfs_isilocked
(
ip
,
XFS_IOLOCK_EXCL
|
XFS_IOLOCK_SHARED
));
ASSERT
((
!
(
lock_flags
&
XFS_IOLOCK_SHARED
))
||
(
ip
->
i_itemp
->
ili_flags
&
XFS_ILI_IOLOCKED_ANY
));
if
(
lock_flags
&
(
XFS_IOLOCK_SHARED
|
XFS_IOLOCK_EXCL
))
{
ip
->
i_itemp
->
ili_iolock_recur
++
;
}
if
(
lock_flags
&
XFS_ILOCK_EXCL
)
{
ip
->
i_itemp
->
ili_ilock_recur
++
;
}
*
ipp
=
ip
;
return
0
;
}
ASSERT
(
lock_flags
&
XFS_ILOCK_EXCL
);
error
=
xfs_iget
(
tp
->
t_mountp
,
tp
,
ino
,
flags
,
lock_flags
,
&
ip
,
0
);
if
(
error
)
{
return
error
;
}
ASSERT
(
ip
!=
NULL
);
xfs_trans_ijoin
(
tp
,
ip
,
lock_flags
);
*
ipp
=
ip
;
return
0
;
error
=
xfs_iget
(
mp
,
tp
,
ino
,
flags
,
lock_flags
,
ipp
,
0
);
if
(
!
error
&&
tp
)
xfs_trans_ijoin
(
tp
,
*
ipp
,
lock_flags
);
return
error
;
}
/*
...
...
@@ -163,8 +89,6 @@ xfs_trans_ijoin(
xfs_inode_item_init
(
ip
,
ip
->
i_mount
);
iip
=
ip
->
i_itemp
;
ASSERT
(
iip
->
ili_flags
==
0
);
ASSERT
(
iip
->
ili_ilock_recur
==
0
);
ASSERT
(
iip
->
ili_iolock_recur
==
0
);
/*
* Get a log_item_desc to point at the new item.
...
...
fs/xfs/xfs_vnodeops.c
View file @
fdec29c5
...
...
@@ -611,7 +611,7 @@ xfs_fsync(
xfs_inode_t
*
ip
)
{
xfs_trans_t
*
tp
;
int
error
;
int
error
=
0
;
int
log_flushed
=
0
,
changed
=
1
;
xfs_itrace_entry
(
ip
);
...
...
@@ -619,14 +619,9 @@ xfs_fsync(
if
(
XFS_FORCED_SHUTDOWN
(
ip
->
i_mount
))
return
XFS_ERROR
(
EIO
);
/* capture size updates in I/O completion before writing the inode. */
error
=
xfs_wait_on_pages
(
ip
,
0
,
-
1
);
if
(
error
)
return
XFS_ERROR
(
error
);
/*
* We always need to make sure that the required inode state is safe on
* disk. The
v
node might be clean but we still might need to force the
* disk. The
i
node might be clean but we still might need to force the
* log because of committed transactions that haven't hit the disk yet.
* Likewise, there could be unflushed non-transactional changes to the
* inode core that have to go to disk and this requires us to issue
...
...
@@ -638,7 +633,7 @@ xfs_fsync(
*/
xfs_ilock
(
ip
,
XFS_ILOCK_SHARED
);
if
(
!
(
ip
->
i_update_size
||
ip
->
i_update_core
)
)
{
if
(
!
ip
->
i_update_core
)
{
/*
* Timestamps/size haven't changed since last inode flush or
* inode transaction commit. That means either nothing got
...
...
@@ -718,7 +713,7 @@ xfs_fsync(
* when the link count isn't zero and by xfs_dm_punch_hole() when
* punching a hole to EOF.
*/
int
STATIC
int
xfs_free_eofblocks
(
xfs_mount_t
*
mp
,
xfs_inode_t
*
ip
,
...
...
@@ -1476,8 +1471,8 @@ xfs_create(
if
(
error
==
ENOSPC
)
{
/* flush outstanding delalloc blocks and retry */
xfs_flush_inodes
(
dp
);
error
=
xfs_trans_reserve
(
tp
,
resblks
,
XFS_CREATE_LOG_RES
(
mp
)
,
0
,
XFS_TRANS_PERM_LOG_RES
,
XFS_CREATE_LOG_COUNT
);
error
=
xfs_trans_reserve
(
tp
,
resblks
,
log_res
,
0
,
XFS_TRANS_PERM_LOG_RES
,
log_count
);
}
if
(
error
==
ENOSPC
)
{
/* No space at all so try a "no-allocation" reservation */
...
...
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