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
dc2a5536
Commit
dc2a5536
authored
Apr 09, 2009
by
Felix Blyakher
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into for-linus
parents
f36345ff
8de2bf93
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
180 additions
and
161 deletions
+180
-161
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_aops.c
+21
-17
fs/xfs/linux-2.6/xfs_aops.h
fs/xfs/linux-2.6/xfs_aops.h
+1
-0
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_buf.c
+9
-0
fs/xfs/linux-2.6/xfs_fs_subr.c
fs/xfs/linux-2.6/xfs_fs_subr.c
+7
-7
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_lrw.c
+17
-1
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.c
+33
-45
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/linux-2.6/xfs_sync.h
+5
-4
fs/xfs/xfs_iget.c
fs/xfs/xfs_iget.c
+14
-9
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iomap.c
+15
-46
fs/xfs/xfs_iomap.h
fs/xfs/xfs_iomap.h
+1
-2
fs/xfs/xfs_log.c
fs/xfs/xfs_log.c
+49
-29
fs/xfs/xfs_mount.h
fs/xfs/xfs_mount.h
+1
-1
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.c
+7
-0
No files found.
fs/xfs/linux-2.6/xfs_aops.c
View file @
dc2a5536
...
...
@@ -152,23 +152,6 @@ xfs_find_bdev_for_inode(
return
mp
->
m_ddev_targp
->
bt_bdev
;
}
/*
* Schedule IO completion handling on a xfsdatad if this was
* the final hold on this ioend. If we are asked to wait,
* flush the workqueue.
*/
STATIC
void
xfs_finish_ioend
(
xfs_ioend_t
*
ioend
,
int
wait
)
{
if
(
atomic_dec_and_test
(
&
ioend
->
io_remaining
))
{
queue_work
(
xfsdatad_workqueue
,
&
ioend
->
io_work
);
if
(
wait
)
flush_workqueue
(
xfsdatad_workqueue
);
}
}
/*
* We're now finished for good with this ioend structure.
* Update the page state via the associated buffer_heads,
...
...
@@ -309,6 +292,27 @@ xfs_end_bio_read(
xfs_destroy_ioend
(
ioend
);
}
/*
* Schedule IO completion handling on a xfsdatad if this was
* the final hold on this ioend. If we are asked to wait,
* flush the workqueue.
*/
STATIC
void
xfs_finish_ioend
(
xfs_ioend_t
*
ioend
,
int
wait
)
{
if
(
atomic_dec_and_test
(
&
ioend
->
io_remaining
))
{
struct
workqueue_struct
*
wq
=
xfsdatad_workqueue
;
if
(
ioend
->
io_work
.
func
==
xfs_end_bio_unwritten
)
wq
=
xfsconvertd_workqueue
;
queue_work
(
wq
,
&
ioend
->
io_work
);
if
(
wait
)
flush_workqueue
(
wq
);
}
}
/*
* Allocate and initialise an IO completion structure.
* We need to track unwritten extent write completion here initially.
...
...
fs/xfs/linux-2.6/xfs_aops.h
View file @
dc2a5536
...
...
@@ -19,6 +19,7 @@
#define __XFS_AOPS_H__
extern
struct
workqueue_struct
*
xfsdatad_workqueue
;
extern
struct
workqueue_struct
*
xfsconvertd_workqueue
;
extern
mempool_t
*
xfs_ioend_pool
;
/*
...
...
fs/xfs/linux-2.6/xfs_buf.c
View file @
dc2a5536
...
...
@@ -51,6 +51,7 @@ static struct shrinker xfs_buf_shake = {
static
struct
workqueue_struct
*
xfslogd_workqueue
;
struct
workqueue_struct
*
xfsdatad_workqueue
;
struct
workqueue_struct
*
xfsconvertd_workqueue
;
#ifdef XFS_BUF_TRACE
void
...
...
@@ -1775,6 +1776,7 @@ xfs_flush_buftarg(
xfs_buf_t
*
bp
,
*
n
;
int
pincount
=
0
;
xfs_buf_runall_queues
(
xfsconvertd_workqueue
);
xfs_buf_runall_queues
(
xfsdatad_workqueue
);
xfs_buf_runall_queues
(
xfslogd_workqueue
);
...
...
@@ -1831,9 +1833,15 @@ xfs_buf_init(void)
if
(
!
xfsdatad_workqueue
)
goto
out_destroy_xfslogd_workqueue
;
xfsconvertd_workqueue
=
create_workqueue
(
"xfsconvertd"
);
if
(
!
xfsconvertd_workqueue
)
goto
out_destroy_xfsdatad_workqueue
;
register_shrinker
(
&
xfs_buf_shake
);
return
0
;
out_destroy_xfsdatad_workqueue:
destroy_workqueue
(
xfsdatad_workqueue
);
out_destroy_xfslogd_workqueue:
destroy_workqueue
(
xfslogd_workqueue
);
out_free_buf_zone:
...
...
@@ -1849,6 +1857,7 @@ void
xfs_buf_terminate
(
void
)
{
unregister_shrinker
(
&
xfs_buf_shake
);
destroy_workqueue
(
xfsconvertd_workqueue
);
destroy_workqueue
(
xfsdatad_workqueue
);
destroy_workqueue
(
xfslogd_workqueue
);
kmem_zone_destroy
(
xfs_buf_zone
);
...
...
fs/xfs/linux-2.6/xfs_fs_subr.c
View file @
dc2a5536
...
...
@@ -74,14 +74,14 @@ xfs_flush_pages(
if
(
mapping_tagged
(
mapping
,
PAGECACHE_TAG_DIRTY
))
{
xfs_iflags_clear
(
ip
,
XFS_ITRUNCATED
);
ret
=
filemap_fdatawrite
(
mapping
);
if
(
flags
&
XFS_B_ASYNC
)
return
-
ret
;
ret2
=
filemap_fdatawait
(
mapping
);
if
(
!
ret
)
ret
=
ret2
;
ret
=
-
filemap_fdatawrite
(
mapping
);
}
return
-
ret
;
if
(
flags
&
XFS_B_ASYNC
)
return
ret
;
ret2
=
xfs_wait_on_pages
(
ip
,
first
,
last
);
if
(
!
ret
)
ret
=
ret2
;
return
ret
;
}
int
...
...
fs/xfs/linux-2.6/xfs_lrw.c
View file @
dc2a5536
...
...
@@ -751,10 +751,26 @@ start:
goto
relock
;
}
}
else
{
int
enospc
=
0
;
ssize_t
ret2
=
0
;
write_retry:
xfs_rw_enter_trace
(
XFS_WRITE_ENTER
,
xip
,
(
void
*
)
iovp
,
segs
,
*
offset
,
ioflags
);
ret
=
generic_file_buffered_write
(
iocb
,
iovp
,
segs
,
ret
2
=
generic_file_buffered_write
(
iocb
,
iovp
,
segs
,
pos
,
offset
,
count
,
ret
);
/*
* if we just got an ENOSPC, flush the inode now we
* aren't holding any page locks and retry *once*
*/
if
(
ret2
==
-
ENOSPC
&&
!
enospc
)
{
error
=
xfs_flush_pages
(
xip
,
0
,
-
1
,
0
,
FI_NONE
);
if
(
error
)
goto
out_unlock_internal
;
enospc
=
1
;
goto
write_retry
;
}
ret
=
ret2
;
}
current
->
backing_dev_info
=
NULL
;
...
...
fs/xfs/linux-2.6/xfs_sync.c
View file @
dc2a5536
...
...
@@ -62,12 +62,6 @@ xfs_sync_inodes_ag(
uint32_t
first_index
=
0
;
int
error
=
0
;
int
last_error
=
0
;
int
fflag
=
XFS_B_ASYNC
;
if
(
flags
&
SYNC_DELWRI
)
fflag
=
XFS_B_DELWRI
;
if
(
flags
&
SYNC_WAIT
)
fflag
=
0
;
/* synchronous overrides all */
do
{
struct
inode
*
inode
;
...
...
@@ -128,11 +122,23 @@ xfs_sync_inodes_ag(
* If we have to flush data or wait for I/O completion
* we need to hold the iolock.
*/
if
((
flags
&
SYNC_DELWRI
)
&&
VN_DIRTY
(
inode
))
{
xfs_ilock
(
ip
,
XFS_IOLOCK_SHARED
);
lock_flags
|=
XFS_IOLOCK_SHARED
;
error
=
xfs_flush_pages
(
ip
,
0
,
-
1
,
fflag
,
FI_NONE
);
if
(
flags
&
SYNC_IOWAIT
)
if
(
flags
&
SYNC_DELWRI
)
{
if
(
VN_DIRTY
(
inode
))
{
if
(
flags
&
SYNC_TRYLOCK
)
{
if
(
xfs_ilock_nowait
(
ip
,
XFS_IOLOCK_SHARED
))
lock_flags
|=
XFS_IOLOCK_SHARED
;
}
else
{
xfs_ilock
(
ip
,
XFS_IOLOCK_SHARED
);
lock_flags
|=
XFS_IOLOCK_SHARED
;
}
if
(
lock_flags
&
XFS_IOLOCK_SHARED
)
{
error
=
xfs_flush_pages
(
ip
,
0
,
-
1
,
(
flags
&
SYNC_WAIT
)
?
0
:
XFS_B_ASYNC
,
FI_NONE
);
}
}
if
(
VN_CACHED
(
inode
)
&&
(
flags
&
SYNC_IOWAIT
))
xfs_ioend_wait
(
ip
);
}
xfs_ilock
(
ip
,
XFS_ILOCK_SHARED
);
...
...
@@ -398,15 +404,17 @@ STATIC void
xfs_syncd_queue_work
(
struct
xfs_mount
*
mp
,
void
*
data
,
void
(
*
syncer
)(
struct
xfs_mount
*
,
void
*
))
void
(
*
syncer
)(
struct
xfs_mount
*
,
void
*
),
struct
completion
*
completion
)
{
struct
bhv_v
fs_sync_work
*
work
;
struct
x
fs_sync_work
*
work
;
work
=
kmem_alloc
(
sizeof
(
struct
bhv_v
fs_sync_work
),
KM_SLEEP
);
work
=
kmem_alloc
(
sizeof
(
struct
x
fs_sync_work
),
KM_SLEEP
);
INIT_LIST_HEAD
(
&
work
->
w_list
);
work
->
w_syncer
=
syncer
;
work
->
w_data
=
data
;
work
->
w_mount
=
mp
;
work
->
w_completion
=
completion
;
spin_lock
(
&
mp
->
m_sync_lock
);
list_add_tail
(
&
work
->
w_list
,
&
mp
->
m_sync_list
);
spin_unlock
(
&
mp
->
m_sync_lock
);
...
...
@@ -420,49 +428,26 @@ xfs_syncd_queue_work(
* heads, looking about for more room...
*/
STATIC
void
xfs_flush_inode_work
(
struct
xfs_mount
*
mp
,
void
*
arg
)
{
struct
inode
*
inode
=
arg
;
filemap_flush
(
inode
->
i_mapping
);
iput
(
inode
);
}
void
xfs_flush_inode
(
xfs_inode_t
*
ip
)
{
struct
inode
*
inode
=
VFS_I
(
ip
);
igrab
(
inode
);
xfs_syncd_queue_work
(
ip
->
i_mount
,
inode
,
xfs_flush_inode_work
);
delay
(
msecs_to_jiffies
(
500
));
}
/*
* This is the "bigger hammer" version of xfs_flush_inode_work...
* (IOW, "If at first you don't succeed, use a Bigger Hammer").
*/
STATIC
void
xfs_flush_device_work
(
xfs_flush_inodes_work
(
struct
xfs_mount
*
mp
,
void
*
arg
)
{
struct
inode
*
inode
=
arg
;
sync_blockdev
(
mp
->
m_super
->
s_bdev
);
xfs_sync_inodes
(
mp
,
SYNC_DELWRI
|
SYNC_TRYLOCK
);
xfs_sync_inodes
(
mp
,
SYNC_DELWRI
|
SYNC_TRYLOCK
|
SYNC_IOWAIT
);
iput
(
inode
);
}
void
xfs_flush_
device
(
xfs_flush_
inodes
(
xfs_inode_t
*
ip
)
{
struct
inode
*
inode
=
VFS_I
(
ip
);
DECLARE_COMPLETION_ONSTACK
(
completion
);
igrab
(
inode
);
xfs_syncd_queue_work
(
ip
->
i_mount
,
inode
,
xfs_flush_
device_work
);
delay
(
msecs_to_jiffies
(
500
)
);
xfs_syncd_queue_work
(
ip
->
i_mount
,
inode
,
xfs_flush_
inodes_work
,
&
completion
);
wait_for_completion
(
&
completion
);
xfs_log_force
(
ip
->
i_mount
,
(
xfs_lsn_t
)
0
,
XFS_LOG_FORCE
|
XFS_LOG_SYNC
);
}
...
...
@@ -497,7 +482,7 @@ xfssyncd(
{
struct
xfs_mount
*
mp
=
arg
;
long
timeleft
;
bhv_vfs_sync_work_t
*
work
,
*
n
;
xfs_sync_work_t
*
work
,
*
n
;
LIST_HEAD
(
tmp
);
set_freezable
();
...
...
@@ -532,6 +517,8 @@ xfssyncd(
list_del
(
&
work
->
w_list
);
if
(
work
==
&
mp
->
m_sync_work
)
continue
;
if
(
work
->
w_completion
)
complete
(
work
->
w_completion
);
kmem_free
(
work
);
}
}
...
...
@@ -545,6 +532,7 @@ xfs_syncd_init(
{
mp
->
m_sync_work
.
w_syncer
=
xfs_sync_worker
;
mp
->
m_sync_work
.
w_mount
=
mp
;
mp
->
m_sync_work
.
w_completion
=
NULL
;
mp
->
m_sync_task
=
kthread_run
(
xfssyncd
,
mp
,
"xfssyncd"
);
if
(
IS_ERR
(
mp
->
m_sync_task
))
return
-
PTR_ERR
(
mp
->
m_sync_task
);
...
...
fs/xfs/linux-2.6/xfs_sync.h
View file @
dc2a5536
...
...
@@ -21,18 +21,20 @@
struct
xfs_mount
;
struct
xfs_perag
;
typedef
struct
bhv_v
fs_sync_work
{
typedef
struct
x
fs_sync_work
{
struct
list_head
w_list
;
struct
xfs_mount
*
w_mount
;
void
*
w_data
;
/* syncer routine argument */
void
(
*
w_syncer
)(
struct
xfs_mount
*
,
void
*
);
}
bhv_vfs_sync_work_t
;
struct
completion
*
w_completion
;
}
xfs_sync_work_t
;
#define SYNC_ATTR 0x0001
/* sync attributes */
#define SYNC_DELWRI 0x0002
/* look at delayed writes */
#define SYNC_WAIT 0x0004
/* wait for i/o to complete */
#define SYNC_BDFLUSH 0x0008
/* BDFLUSH is calling -- don't block */
#define SYNC_IOWAIT 0x0010
/* wait for all I/O to complete */
#define SYNC_TRYLOCK 0x0020
/* only try to lock inodes */
int
xfs_syncd_init
(
struct
xfs_mount
*
mp
);
void
xfs_syncd_stop
(
struct
xfs_mount
*
mp
);
...
...
@@ -43,8 +45,7 @@ int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
int
xfs_quiesce_data
(
struct
xfs_mount
*
mp
);
void
xfs_quiesce_attr
(
struct
xfs_mount
*
mp
);
void
xfs_flush_inode
(
struct
xfs_inode
*
ip
);
void
xfs_flush_device
(
struct
xfs_inode
*
ip
);
void
xfs_flush_inodes
(
struct
xfs_inode
*
ip
);
int
xfs_reclaim_inode
(
struct
xfs_inode
*
ip
,
int
locked
,
int
sync_mode
);
int
xfs_reclaim_inodes
(
struct
xfs_mount
*
mp
,
int
noblock
,
int
mode
);
...
...
fs/xfs/xfs_iget.c
View file @
dc2a5536
...
...
@@ -69,15 +69,6 @@ xfs_inode_alloc(
ASSERT
(
!
spin_is_locked
(
&
ip
->
i_flags_lock
));
ASSERT
(
completion_done
(
&
ip
->
i_flush
));
/*
* initialise the VFS inode here to get failures
* out of the way early.
*/
if
(
!
inode_init_always
(
mp
->
m_super
,
VFS_I
(
ip
)))
{
kmem_zone_free
(
xfs_inode_zone
,
ip
);
return
NULL
;
}
/* initialise the xfs inode */
ip
->
i_ino
=
ino
;
ip
->
i_mount
=
mp
;
...
...
@@ -113,6 +104,20 @@ xfs_inode_alloc(
#ifdef XFS_DIR2_TRACE
ip
->
i_dir_trace
=
ktrace_alloc
(
XFS_DIR2_KTRACE_SIZE
,
KM_NOFS
);
#endif
/*
* Now initialise the VFS inode. We do this after the xfs_inode
* initialisation as internal failures will result in ->destroy_inode
* being called and that will pass down through the reclaim path and
* free the XFS inode. This path requires the XFS inode to already be
* initialised. Hence if this call fails, the xfs_inode has already
* been freed and we should not reference it at all in the error
* handling.
*/
if
(
!
inode_init_always
(
mp
->
m_super
,
VFS_I
(
ip
)))
return
NULL
;
/* prevent anyone from using this yet */
VFS_I
(
ip
)
->
i_state
=
I_NEW
|
I_LOCK
;
return
ip
;
}
...
...
fs/xfs/xfs_iomap.c
View file @
dc2a5536
...
...
@@ -337,38 +337,6 @@ xfs_iomap_eof_align_last_fsb(
return
0
;
}
STATIC
int
xfs_flush_space
(
xfs_inode_t
*
ip
,
int
*
fsynced
,
int
*
ioflags
)
{
switch
(
*
fsynced
)
{
case
0
:
if
(
ip
->
i_delayed_blks
)
{
xfs_iunlock
(
ip
,
XFS_ILOCK_EXCL
);
xfs_flush_inode
(
ip
);
xfs_ilock
(
ip
,
XFS_ILOCK_EXCL
);
*
fsynced
=
1
;
}
else
{
*
ioflags
|=
BMAPI_SYNC
;
*
fsynced
=
2
;
}
return
0
;
case
1
:
*
fsynced
=
2
;
*
ioflags
|=
BMAPI_SYNC
;
return
0
;
case
2
:
xfs_iunlock
(
ip
,
XFS_ILOCK_EXCL
);
xfs_flush_device
(
ip
);
xfs_ilock
(
ip
,
XFS_ILOCK_EXCL
);
*
fsynced
=
3
;
return
0
;
}
return
1
;
}
STATIC
int
xfs_cmn_err_fsblock_zero
(
xfs_inode_t
*
ip
,
...
...
@@ -538,15 +506,9 @@ error_out:
}
/*
* If the caller is doing a write at the end of the file,
* then extend the allocation out to the file system's write
* iosize. We clean up any extra space left over when the
* file is closed in xfs_inactive().
*
* For sync writes, we are flushing delayed allocate space to
* try to make additional space available for allocation near
* the filesystem full boundary - preallocation hurts in that
* situation, of course.
* If the caller is doing a write at the end of the file, then extend the
* allocation out to the file system's write iosize. We clean up any extra
* space left over when the file is closed in xfs_inactive().
*/
STATIC
int
xfs_iomap_eof_want_preallocate
(
...
...
@@ -565,7 +527,7 @@ xfs_iomap_eof_want_preallocate(
int
n
,
error
,
imaps
;
*
prealloc
=
0
;
if
((
ioflag
&
BMAPI_SYNC
)
||
(
offset
+
count
)
<=
ip
->
i_size
)
if
((
offset
+
count
)
<=
ip
->
i_size
)
return
0
;
/*
...
...
@@ -611,7 +573,7 @@ xfs_iomap_write_delay(
xfs_extlen_t
extsz
;
int
nimaps
;
xfs_bmbt_irec_t
imap
[
XFS_WRITE_IMAPS
];
int
prealloc
,
f
sync
ed
=
0
;
int
prealloc
,
f
lush
ed
=
0
;
int
error
;
ASSERT
(
xfs_isilocked
(
ip
,
XFS_ILOCK_EXCL
));
...
...
@@ -627,12 +589,12 @@ xfs_iomap_write_delay(
extsz
=
xfs_get_extsz_hint
(
ip
);
offset_fsb
=
XFS_B_TO_FSBT
(
mp
,
offset
);
retry:
error
=
xfs_iomap_eof_want_preallocate
(
mp
,
ip
,
offset
,
count
,
ioflag
,
imap
,
XFS_WRITE_IMAPS
,
&
prealloc
);
if
(
error
)
return
error
;
retry:
if
(
prealloc
)
{
aligned_offset
=
XFS_WRITEIO_ALIGN
(
mp
,
(
offset
+
count
-
1
));
ioalign
=
XFS_B_TO_FSBT
(
mp
,
aligned_offset
);
...
...
@@ -659,15 +621,22 @@ retry:
/*
* If bmapi returned us nothing, and if we didn't get back EDQUOT,
* then we must have run out of space - flush delalloc, and retry..
* then we must have run out of space - flush all other inodes with
* delalloc blocks and retry without EOF preallocation.
*/
if
(
nimaps
==
0
)
{
xfs_iomap_enter_trace
(
XFS_IOMAP_WRITE_NOSPACE
,
ip
,
offset
,
count
);
if
(
xfs_flush_space
(
ip
,
&
fsynced
,
&
ioflag
)
)
if
(
flushed
)
return
XFS_ERROR
(
ENOSPC
);
xfs_iunlock
(
ip
,
XFS_ILOCK_EXCL
);
xfs_flush_inodes
(
ip
);
xfs_ilock
(
ip
,
XFS_ILOCK_EXCL
);
flushed
=
1
;
error
=
0
;
prealloc
=
0
;
goto
retry
;
}
...
...
fs/xfs/xfs_iomap.h
View file @
dc2a5536
...
...
@@ -40,8 +40,7 @@ typedef enum {
BMAPI_IGNSTATE
=
(
1
<<
4
),
/* ignore unwritten state on read */
BMAPI_DIRECT
=
(
1
<<
5
),
/* direct instead of buffered write */
BMAPI_MMAP
=
(
1
<<
6
),
/* allocate for mmap write */
BMAPI_SYNC
=
(
1
<<
7
),
/* sync write to flush delalloc space */
BMAPI_TRYLOCK
=
(
1
<<
8
),
/* non-blocking request */
BMAPI_TRYLOCK
=
(
1
<<
7
),
/* non-blocking request */
}
bmapi_flags_t
;
...
...
fs/xfs/xfs_log.c
View file @
dc2a5536
...
...
@@ -562,9 +562,8 @@ xfs_log_mount(
}
mp
->
m_log
=
xlog_alloc_log
(
mp
,
log_target
,
blk_offset
,
num_bblks
);
if
(
!
mp
->
m_log
)
{
cmn_err
(
CE_WARN
,
"XFS: Log allocation failed: No memory!"
);
error
=
ENOMEM
;
if
(
IS_ERR
(
mp
->
m_log
))
{
error
=
-
PTR_ERR
(
mp
->
m_log
);
goto
out
;
}
...
...
@@ -1180,10 +1179,13 @@ xlog_alloc_log(xfs_mount_t *mp,
xfs_buf_t
*
bp
;
int
i
;
int
iclogsize
;
int
error
=
ENOMEM
;
log
=
kmem_zalloc
(
sizeof
(
xlog_t
),
KM_MAYFAIL
);
if
(
!
log
)
return
NULL
;
if
(
!
log
)
{
xlog_warn
(
"XFS: Log allocation failed: No memory!"
);
goto
out
;
}
log
->
l_mp
=
mp
;
log
->
l_targ
=
log_target
;
...
...
@@ -1201,19 +1203,35 @@ xlog_alloc_log(xfs_mount_t *mp,
log
->
l_grant_reserve_cycle
=
1
;
log
->
l_grant_write_cycle
=
1
;
error
=
EFSCORRUPTED
;
if
(
xfs_sb_version_hassector
(
&
mp
->
m_sb
))
{
log
->
l_sectbb_log
=
mp
->
m_sb
.
sb_logsectlog
-
BBSHIFT
;
ASSERT
(
log
->
l_sectbb_log
<=
mp
->
m_sectbb_log
);
if
(
log
->
l_sectbb_log
<
0
||
log
->
l_sectbb_log
>
mp
->
m_sectbb_log
)
{
xlog_warn
(
"XFS: Log sector size (0x%x) out of range."
,
log
->
l_sectbb_log
);
goto
out_free_log
;
}
/* for larger sector sizes, must have v2 or external log */
ASSERT
(
log
->
l_sectbb_log
==
0
||
log
->
l_logBBstart
==
0
||
xfs_sb_version_haslogv2
(
&
mp
->
m_sb
));
ASSERT
(
mp
->
m_sb
.
sb_logsectlog
>=
BBSHIFT
);
if
(
log
->
l_sectbb_log
!=
0
&&
(
log
->
l_logBBstart
!=
0
&&
!
xfs_sb_version_haslogv2
(
&
mp
->
m_sb
)))
{
xlog_warn
(
"XFS: log sector size (0x%x) invalid "
"for configuration."
,
log
->
l_sectbb_log
);
goto
out_free_log
;
}
if
(
mp
->
m_sb
.
sb_logsectlog
<
BBSHIFT
)
{
xlog_warn
(
"XFS: Log sector log (0x%x) too small."
,
mp
->
m_sb
.
sb_logsectlog
);
goto
out_free_log
;
}
}
log
->
l_sectbb_mask
=
(
1
<<
log
->
l_sectbb_log
)
-
1
;
xlog_get_iclog_buffer_size
(
mp
,
log
);
error
=
ENOMEM
;
bp
=
xfs_buf_get_empty
(
log
->
l_iclog_size
,
mp
->
m_logdev_targp
);
if
(
!
bp
)
goto
out_free_log
;
...
...
@@ -1313,7 +1331,8 @@ out_free_iclog:
xfs_buf_free
(
log
->
l_xbuf
);
out_free_log:
kmem_free
(
log
);
return
NULL
;
out:
return
ERR_PTR
(
-
error
);
}
/* xlog_alloc_log */
...
...
@@ -2541,18 +2560,19 @@ redo:
xlog_ins_ticketq
(
&
log
->
l_reserve_headq
,
tic
);
xlog_trace_loggrant
(
log
,
tic
,
"xlog_grant_log_space: sleep 2"
);
spin_unlock
(
&
log
->
l_grant_lock
);
xlog_grant_push_ail
(
log
->
l_mp
,
need_bytes
);
spin_lock
(
&
log
->
l_grant_lock
);
XFS_STATS_INC
(
xs_sleep_logspace
);
sv_wait
(
&
tic
->
t_wait
,
PINOD
|
PLTWAIT
,
&
log
->
l_grant_lock
,
s
);
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
{
spin_lock
(
&
log
->
l_grant_lock
);
spin_lock
(
&
log
->
l_grant_lock
);
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
goto
error_return
;
}
xlog_trace_loggrant
(
log
,
tic
,
"xlog_grant_log_space: wake 2"
);
xlog_grant_push_ail
(
log
->
l_mp
,
need_bytes
);
spin_lock
(
&
log
->
l_grant_lock
);
goto
redo
;
}
else
if
(
tic
->
t_flags
&
XLOG_TIC_IN_Q
)
xlog_del_ticketq
(
&
log
->
l_reserve_headq
,
tic
);
...
...
@@ -2631,7 +2651,7 @@ xlog_regrant_write_log_space(xlog_t *log,
* for more free space, otherwise try to get some space for
* this transaction.
*/
need_bytes
=
tic
->
t_unit_res
;
if
((
ntic
=
log
->
l_write_headq
))
{
free_bytes
=
xlog_space_left
(
log
,
log
->
l_grant_write_cycle
,
log
->
l_grant_write_bytes
);
...
...
@@ -2651,26 +2671,25 @@ xlog_regrant_write_log_space(xlog_t *log,
xlog_trace_loggrant
(
log
,
tic
,
"xlog_regrant_write_log_space: sleep 1"
);
spin_unlock
(
&
log
->
l_grant_lock
);
xlog_grant_push_ail
(
log
->
l_mp
,
need_bytes
);
spin_lock
(
&
log
->
l_grant_lock
);
XFS_STATS_INC
(
xs_sleep_logspace
);
sv_wait
(
&
tic
->
t_wait
,
PINOD
|
PLTWAIT
,
&
log
->
l_grant_lock
,
s
);
/* If we're shutting down, this tic is already
* off the queue */
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
{
spin_lock
(
&
log
->
l_grant_lock
);
spin_lock
(
&
log
->
l_grant_lock
);
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
goto
error_return
;
}
xlog_trace_loggrant
(
log
,
tic
,
"xlog_regrant_write_log_space: wake 1"
);
xlog_grant_push_ail
(
log
->
l_mp
,
tic
->
t_unit_res
);
spin_lock
(
&
log
->
l_grant_lock
);
}
}
need_bytes
=
tic
->
t_unit_res
;
redo:
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
goto
error_return
;
...
...
@@ -2680,19 +2699,20 @@ redo:
if
(
free_bytes
<
need_bytes
)
{
if
((
tic
->
t_flags
&
XLOG_TIC_IN_Q
)
==
0
)
xlog_ins_ticketq
(
&
log
->
l_write_headq
,
tic
);
spin_unlock
(
&
log
->
l_grant_lock
);
xlog_grant_push_ail
(
log
->
l_mp
,
need_bytes
);
spin_lock
(
&
log
->
l_grant_lock
);
XFS_STATS_INC
(
xs_sleep_logspace
);
sv_wait
(
&
tic
->
t_wait
,
PINOD
|
PLTWAIT
,
&
log
->
l_grant_lock
,
s
);
/* If we're shutting down, this tic is already off the queue */
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
{
spin_lock
(
&
log
->
l_grant_lock
);
spin_lock
(
&
log
->
l_grant_lock
);
if
(
XLOG_FORCED_SHUTDOWN
(
log
))
goto
error_return
;
}
xlog_trace_loggrant
(
log
,
tic
,
"xlog_regrant_write_log_space: wake 2"
);
xlog_grant_push_ail
(
log
->
l_mp
,
need_bytes
);
spin_lock
(
&
log
->
l_grant_lock
);
goto
redo
;
}
else
if
(
tic
->
t_flags
&
XLOG_TIC_IN_Q
)
xlog_del_ticketq
(
&
log
->
l_write_headq
,
tic
);
...
...
fs/xfs/xfs_mount.h
View file @
dc2a5536
...
...
@@ -313,7 +313,7 @@ typedef struct xfs_mount {
#endif
struct
xfs_mru_cache
*
m_filestream
;
/* per-mount filestream data */
struct
task_struct
*
m_sync_task
;
/* generalised sync thread */
bhv_vfs_sync_work_t
m_sync_work
;
/* work item for VFS_SYNC */
xfs_sync_work_t
m_sync_work
;
/* work item for VFS_SYNC */
struct
list_head
m_sync_list
;
/* sync thread work item list */
spinlock_t
m_sync_lock
;
/* work item list lock */
int
m_sync_seq
;
/* sync thread generation no. */
...
...
fs/xfs/xfs_vnodeops.c
View file @
dc2a5536
...
...
@@ -1457,6 +1457,13 @@ xfs_create(
error
=
xfs_trans_reserve
(
tp
,
resblks
,
log_res
,
0
,
XFS_TRANS_PERM_LOG_RES
,
log_count
);
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
);
}
if
(
error
==
ENOSPC
)
{
/* No space at all so try a "no-allocation" reservation */
resblks
=
0
;
error
=
xfs_trans_reserve
(
tp
,
0
,
log_res
,
0
,
XFS_TRANS_PERM_LOG_RES
,
log_count
);
...
...
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