@@ -357,7 +357,7 @@ u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
357
357
358
358
struct fuse_writepage_args {
359
359
struct fuse_io_args ia ;
360
- struct list_head writepages_entry ;
360
+ struct rb_node writepages_entry ;
361
361
struct list_head queue_entry ;
362
362
struct fuse_writepage_args * next ;
363
363
struct inode * inode ;
@@ -366,17 +366,23 @@ struct fuse_writepage_args {
366
366
static struct fuse_writepage_args * fuse_find_writeback (struct fuse_inode * fi ,
367
367
pgoff_t idx_from , pgoff_t idx_to )
368
368
{
369
- struct fuse_writepage_args * wpa ;
369
+ struct rb_node * n ;
370
+
371
+ n = fi -> writepages .rb_node ;
370
372
371
- list_for_each_entry (wpa , & fi -> writepages , writepages_entry ) {
373
+ while (n ) {
374
+ struct fuse_writepage_args * wpa ;
372
375
pgoff_t curr_index ;
373
376
377
+ wpa = rb_entry (n , struct fuse_writepage_args , writepages_entry );
374
378
WARN_ON (get_fuse_inode (wpa -> inode ) != fi );
375
379
curr_index = wpa -> ia .write .in .offset >> PAGE_SHIFT ;
376
- if (idx_from < curr_index + wpa -> ia .ap .num_pages &&
377
- curr_index <= idx_to ) {
380
+ if (idx_from >= curr_index + wpa -> ia .ap .num_pages )
381
+ n = n -> rb_right ;
382
+ else if (idx_to < curr_index )
383
+ n = n -> rb_left ;
384
+ else
378
385
return wpa ;
379
- }
380
386
}
381
387
return NULL ;
382
388
}
@@ -1624,7 +1630,7 @@ static void fuse_writepage_finish(struct fuse_conn *fc,
1624
1630
struct backing_dev_info * bdi = inode_to_bdi (inode );
1625
1631
int i ;
1626
1632
1627
- list_del (& wpa -> writepages_entry );
1633
+ rb_erase (& wpa -> writepages_entry , & fi -> writepages );
1628
1634
for (i = 0 ; i < ap -> num_pages ; i ++ ) {
1629
1635
dec_wb_stat (& bdi -> wb , WB_WRITEBACK );
1630
1636
dec_node_page_state (ap -> pages [i ], NR_WRITEBACK_TEMP );
@@ -1712,6 +1718,36 @@ __acquires(fi->lock)
1712
1718
}
1713
1719
}
1714
1720
1721
+ static void tree_insert (struct rb_root * root , struct fuse_writepage_args * wpa )
1722
+ {
1723
+ pgoff_t idx_from = wpa -> ia .write .in .offset >> PAGE_SHIFT ;
1724
+ pgoff_t idx_to = idx_from + wpa -> ia .ap .num_pages - 1 ;
1725
+ struct rb_node * * p = & root -> rb_node ;
1726
+ struct rb_node * parent = NULL ;
1727
+
1728
+ WARN_ON (!wpa -> ia .ap .num_pages );
1729
+ while (* p ) {
1730
+ struct fuse_writepage_args * curr ;
1731
+ pgoff_t curr_index ;
1732
+
1733
+ parent = * p ;
1734
+ curr = rb_entry (parent , struct fuse_writepage_args ,
1735
+ writepages_entry );
1736
+ WARN_ON (curr -> inode != wpa -> inode );
1737
+ curr_index = curr -> ia .write .in .offset >> PAGE_SHIFT ;
1738
+
1739
+ if (idx_from >= curr_index + curr -> ia .ap .num_pages )
1740
+ p = & (* p )-> rb_right ;
1741
+ else if (idx_to < curr_index )
1742
+ p = & (* p )-> rb_left ;
1743
+ else
1744
+ return (void ) WARN_ON (true);
1745
+ }
1746
+
1747
+ rb_link_node (& wpa -> writepages_entry , parent , p );
1748
+ rb_insert_color (& wpa -> writepages_entry , root );
1749
+ }
1750
+
1715
1751
static void fuse_writepage_end (struct fuse_conn * fc , struct fuse_args * args ,
1716
1752
int error )
1717
1753
{
@@ -1730,7 +1766,7 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_args *args,
1730
1766
wpa -> next = next -> next ;
1731
1767
next -> next = NULL ;
1732
1768
next -> ia .ff = fuse_file_get (wpa -> ia .ff );
1733
- list_add ( & next -> writepages_entry , & fi -> writepages );
1769
+ tree_insert ( & fi -> writepages , next );
1734
1770
1735
1771
/*
1736
1772
* Skip fuse_flush_writepages() to make it easy to crop requests
@@ -1865,7 +1901,7 @@ static int fuse_writepage_locked(struct page *page)
1865
1901
inc_node_page_state (tmp_page , NR_WRITEBACK_TEMP );
1866
1902
1867
1903
spin_lock (& fi -> lock );
1868
- list_add ( & wpa -> writepages_entry , & fi -> writepages );
1904
+ tree_insert ( & fi -> writepages , wpa );
1869
1905
list_add_tail (& wpa -> queue_entry , & fi -> queued_writes );
1870
1906
fuse_flush_writepages (inode );
1871
1907
spin_unlock (& fi -> lock );
@@ -1977,10 +2013,10 @@ static bool fuse_writepage_in_flight(struct fuse_writepage_args *new_wpa,
1977
2013
WARN_ON (new_ap -> num_pages != 0 );
1978
2014
1979
2015
spin_lock (& fi -> lock );
1980
- list_del (& new_wpa -> writepages_entry );
2016
+ rb_erase (& new_wpa -> writepages_entry , & fi -> writepages );
1981
2017
old_wpa = fuse_find_writeback (fi , page -> index , page -> index );
1982
2018
if (!old_wpa ) {
1983
- list_add ( & new_wpa -> writepages_entry , & fi -> writepages );
2019
+ tree_insert ( & fi -> writepages , new_wpa );
1984
2020
spin_unlock (& fi -> lock );
1985
2021
return false;
1986
2022
}
@@ -2095,7 +2131,7 @@ static int fuse_writepages_fill(struct page *page,
2095
2131
wpa -> inode = inode ;
2096
2132
2097
2133
spin_lock (& fi -> lock );
2098
- list_add ( & wpa -> writepages_entry , & fi -> writepages );
2134
+ tree_insert ( & fi -> writepages , wpa );
2099
2135
spin_unlock (& fi -> lock );
2100
2136
2101
2137
data -> wpa = wpa ;
@@ -3405,5 +3441,5 @@ void fuse_init_file_inode(struct inode *inode)
3405
3441
INIT_LIST_HEAD (& fi -> queued_writes );
3406
3442
fi -> writectr = 0 ;
3407
3443
init_waitqueue_head (& fi -> page_waitq );
3408
- INIT_LIST_HEAD ( & fi -> writepages ) ;
3444
+ fi -> writepages = RB_ROOT ;
3409
3445
}
0 commit comments