@@ -5872,6 +5872,74 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
58725872 return d_splice_alias (inode , dentry );
58735873}
58745874
5875+ /*
5876+ * Find the highest existing sequence number in a directory and then set the
5877+ * in-memory index_cnt variable to the first free sequence number.
5878+ */
5879+ static int btrfs_set_inode_index_count (struct btrfs_inode * inode )
5880+ {
5881+ struct btrfs_root * root = inode -> root ;
5882+ struct btrfs_key key , found_key ;
5883+ struct btrfs_path * path ;
5884+ struct extent_buffer * leaf ;
5885+ int ret ;
5886+
5887+ key .objectid = btrfs_ino (inode );
5888+ key .type = BTRFS_DIR_INDEX_KEY ;
5889+ key .offset = (u64 )- 1 ;
5890+
5891+ path = btrfs_alloc_path ();
5892+ if (!path )
5893+ return - ENOMEM ;
5894+
5895+ ret = btrfs_search_slot (NULL , root , & key , path , 0 , 0 );
5896+ if (ret < 0 )
5897+ goto out ;
5898+ /* FIXME: we should be able to handle this */
5899+ if (ret == 0 )
5900+ goto out ;
5901+ ret = 0 ;
5902+
5903+ if (path -> slots [0 ] == 0 ) {
5904+ inode -> index_cnt = BTRFS_DIR_START_INDEX ;
5905+ goto out ;
5906+ }
5907+
5908+ path -> slots [0 ]-- ;
5909+
5910+ leaf = path -> nodes [0 ];
5911+ btrfs_item_key_to_cpu (leaf , & found_key , path -> slots [0 ]);
5912+
5913+ if (found_key .objectid != btrfs_ino (inode ) ||
5914+ found_key .type != BTRFS_DIR_INDEX_KEY ) {
5915+ inode -> index_cnt = BTRFS_DIR_START_INDEX ;
5916+ goto out ;
5917+ }
5918+
5919+ inode -> index_cnt = found_key .offset + 1 ;
5920+ out :
5921+ btrfs_free_path (path );
5922+ return ret ;
5923+ }
5924+
5925+ static int btrfs_get_dir_last_index (struct btrfs_inode * dir , u64 * index )
5926+ {
5927+ if (dir -> index_cnt == (u64 )- 1 ) {
5928+ int ret ;
5929+
5930+ ret = btrfs_inode_delayed_dir_index_count (dir );
5931+ if (ret ) {
5932+ ret = btrfs_set_inode_index_count (dir );
5933+ if (ret )
5934+ return ret ;
5935+ }
5936+ }
5937+
5938+ * index = dir -> index_cnt ;
5939+
5940+ return 0 ;
5941+ }
5942+
58755943/*
58765944 * All this infrastructure exists because dir_emit can fault, and we are holding
58775945 * the tree lock when doing readdir. For now just allocate a buffer and copy
@@ -5884,10 +5952,17 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
58845952static int btrfs_opendir (struct inode * inode , struct file * file )
58855953{
58865954 struct btrfs_file_private * private ;
5955+ u64 last_index ;
5956+ int ret ;
5957+
5958+ ret = btrfs_get_dir_last_index (BTRFS_I (inode ), & last_index );
5959+ if (ret )
5960+ return ret ;
58875961
58885962 private = kzalloc (sizeof (struct btrfs_file_private ), GFP_KERNEL );
58895963 if (!private )
58905964 return - ENOMEM ;
5965+ private -> last_index = last_index ;
58915966 private -> filldir_buf = kzalloc (PAGE_SIZE , GFP_KERNEL );
58925967 if (!private -> filldir_buf ) {
58935968 kfree (private );
@@ -5954,7 +6029,8 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
59546029
59556030 INIT_LIST_HEAD (& ins_list );
59566031 INIT_LIST_HEAD (& del_list );
5957- put = btrfs_readdir_get_delayed_items (inode , & ins_list , & del_list );
6032+ put = btrfs_readdir_get_delayed_items (inode , private -> last_index ,
6033+ & ins_list , & del_list );
59586034
59596035again :
59606036 key .type = BTRFS_DIR_INDEX_KEY ;
@@ -5972,6 +6048,8 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
59726048 break ;
59736049 if (found_key .offset < ctx -> pos )
59746050 continue ;
6051+ if (found_key .offset > private -> last_index )
6052+ break ;
59756053 if (btrfs_should_delete_dir_index (& del_list , found_key .offset ))
59766054 continue ;
59776055 di = btrfs_item_ptr (leaf , path -> slots [0 ], struct btrfs_dir_item );
@@ -6107,57 +6185,6 @@ static int btrfs_update_time(struct inode *inode, struct timespec64 *now,
61076185 return dirty ? btrfs_dirty_inode (BTRFS_I (inode )) : 0 ;
61086186}
61096187
6110- /*
6111- * find the highest existing sequence number in a directory
6112- * and then set the in-memory index_cnt variable to reflect
6113- * free sequence numbers
6114- */
6115- static int btrfs_set_inode_index_count (struct btrfs_inode * inode )
6116- {
6117- struct btrfs_root * root = inode -> root ;
6118- struct btrfs_key key , found_key ;
6119- struct btrfs_path * path ;
6120- struct extent_buffer * leaf ;
6121- int ret ;
6122-
6123- key .objectid = btrfs_ino (inode );
6124- key .type = BTRFS_DIR_INDEX_KEY ;
6125- key .offset = (u64 )- 1 ;
6126-
6127- path = btrfs_alloc_path ();
6128- if (!path )
6129- return - ENOMEM ;
6130-
6131- ret = btrfs_search_slot (NULL , root , & key , path , 0 , 0 );
6132- if (ret < 0 )
6133- goto out ;
6134- /* FIXME: we should be able to handle this */
6135- if (ret == 0 )
6136- goto out ;
6137- ret = 0 ;
6138-
6139- if (path -> slots [0 ] == 0 ) {
6140- inode -> index_cnt = BTRFS_DIR_START_INDEX ;
6141- goto out ;
6142- }
6143-
6144- path -> slots [0 ]-- ;
6145-
6146- leaf = path -> nodes [0 ];
6147- btrfs_item_key_to_cpu (leaf , & found_key , path -> slots [0 ]);
6148-
6149- if (found_key .objectid != btrfs_ino (inode ) ||
6150- found_key .type != BTRFS_DIR_INDEX_KEY ) {
6151- inode -> index_cnt = BTRFS_DIR_START_INDEX ;
6152- goto out ;
6153- }
6154-
6155- inode -> index_cnt = found_key .offset + 1 ;
6156- out :
6157- btrfs_free_path (path );
6158- return ret ;
6159- }
6160-
61616188/*
61626189 * helper to find a free sequence number in a given directory. This current
61636190 * code is very simple, later versions will do smarter things in the btree
0 commit comments