@@ -26,6 +26,7 @@ static int afs_dir_open(struct inode *inode, struct file *file);
2626static int afs_readdir (struct file * file , struct dir_context * ctx );
2727static int afs_d_revalidate (struct dentry * dentry , unsigned int flags );
2828static int afs_d_delete (const struct dentry * dentry );
29+ static void afs_d_iput (struct dentry * dentry , struct inode * inode );
2930static int afs_lookup_one_filldir (struct dir_context * ctx , const char * name , int nlen ,
3031 loff_t fpos , u64 ino , unsigned dtype );
3132static int afs_lookup_filldir (struct dir_context * ctx , const char * name , int nlen ,
@@ -85,6 +86,7 @@ const struct dentry_operations afs_fs_dentry_operations = {
8586 .d_delete = afs_d_delete ,
8687 .d_release = afs_d_release ,
8788 .d_automount = afs_d_automount ,
89+ .d_iput = afs_d_iput ,
8890};
8991
9092struct afs_lookup_one_cookie {
@@ -159,6 +161,38 @@ static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page,
159161 return false;
160162}
161163
164+ /*
165+ * Check the contents of a directory that we've just read.
166+ */
167+ static bool afs_dir_check_pages (struct afs_vnode * dvnode , struct afs_read * req )
168+ {
169+ struct afs_xdr_dir_page * dbuf ;
170+ unsigned int i , j , qty = PAGE_SIZE / sizeof (union afs_xdr_dir_block );
171+
172+ for (i = 0 ; i < req -> nr_pages ; i ++ )
173+ if (!afs_dir_check_page (dvnode , req -> pages [i ], req -> actual_len ))
174+ goto bad ;
175+ return true;
176+
177+ bad :
178+ pr_warn ("DIR %llx:%llx f=%llx l=%llx al=%llx r=%llx\n" ,
179+ dvnode -> fid .vid , dvnode -> fid .vnode ,
180+ req -> file_size , req -> len , req -> actual_len , req -> remain );
181+ pr_warn ("DIR %llx %x %x %x\n" ,
182+ req -> pos , req -> index , req -> nr_pages , req -> offset );
183+
184+ for (i = 0 ; i < req -> nr_pages ; i ++ ) {
185+ dbuf = kmap (req -> pages [i ]);
186+ for (j = 0 ; j < qty ; j ++ ) {
187+ union afs_xdr_dir_block * block = & dbuf -> blocks [j ];
188+
189+ pr_warn ("[%02x] %32phN\n" , i * qty + j , block );
190+ }
191+ kunmap (req -> pages [i ]);
192+ }
193+ return false;
194+ }
195+
162196/*
163197 * open an AFS directory file
164198 */
@@ -277,6 +311,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
277311 goto error ;
278312
279313 if (!test_bit (AFS_VNODE_DIR_VALID , & dvnode -> flags )) {
314+ trace_afs_reload_dir (dvnode );
280315 ret = afs_fetch_data (dvnode , key , req );
281316 if (ret < 0 )
282317 goto error_unlock ;
@@ -288,10 +323,8 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
288323
289324 /* Validate the data we just read. */
290325 ret = - EIO ;
291- for (i = 0 ; i < req -> nr_pages ; i ++ )
292- if (!afs_dir_check_page (dvnode , req -> pages [i ],
293- req -> actual_len ))
294- goto error_unlock ;
326+ if (!afs_dir_check_pages (dvnode , req ))
327+ goto error_unlock ;
295328
296329 // TODO: Trim excess pages
297330
@@ -743,7 +776,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
743776 ti = afs_iget (dir -> i_sb , key , & cookie -> fids [i ],
744777 & cookie -> statuses [i ],
745778 & cookie -> callbacks [i ],
746- cbi );
779+ cbi , dvnode );
747780 if (i == 0 ) {
748781 inode = ti ;
749782 } else {
@@ -875,8 +908,14 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
875908 (void * )(unsigned long )dvnode -> status .data_version ;
876909 }
877910 d = d_splice_alias (inode , dentry );
878- if (!IS_ERR_OR_NULL (d ))
911+ if (!IS_ERR_OR_NULL (d )) {
879912 d -> d_fsdata = dentry -> d_fsdata ;
913+ trace_afs_lookup (dvnode , & d -> d_name ,
914+ inode ? AFS_FS_I (inode ) : NULL );
915+ } else {
916+ trace_afs_lookup (dvnode , & dentry -> d_name ,
917+ inode ? AFS_FS_I (inode ) : NULL );
918+ }
880919 return d ;
881920}
882921
@@ -1052,6 +1091,16 @@ static int afs_d_delete(const struct dentry *dentry)
10521091 return 1 ;
10531092}
10541093
1094+ /*
1095+ * Clean up sillyrename files on dentry removal.
1096+ */
1097+ static void afs_d_iput (struct dentry * dentry , struct inode * inode )
1098+ {
1099+ if (dentry -> d_flags & DCACHE_NFSFS_RENAMED )
1100+ afs_silly_iput (dentry , inode );
1101+ iput (inode );
1102+ }
1103+
10551104/*
10561105 * handle dentry release
10571106 */
@@ -1076,7 +1125,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
10761125 return ;
10771126
10781127 inode = afs_iget (fc -> vnode -> vfs_inode .i_sb , fc -> key ,
1079- newfid , newstatus , newcb , fc -> cbi );
1128+ newfid , newstatus , newcb , fc -> cbi , fc -> vnode );
10801129 if (IS_ERR (inode )) {
10811130 /* ENOMEM or EINTR at a really inconvenient time - just abandon
10821131 * the new directory on the server.
@@ -1194,6 +1243,12 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
11941243 goto error_key ;
11951244 }
11961245
1246+ if (vnode ) {
1247+ ret = down_write_killable (& vnode -> rmdir_lock );
1248+ if (ret < 0 )
1249+ goto error_key ;
1250+ }
1251+
11971252 ret = - ERESTARTSYS ;
11981253 if (afs_begin_vnode_operation (& fc , dvnode , key )) {
11991254 while (afs_select_fileserver (& fc )) {
@@ -1212,6 +1267,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
12121267 }
12131268 }
12141269
1270+ if (vnode )
1271+ up_write (& vnode -> rmdir_lock );
12151272error_key :
12161273 key_put (key );
12171274error :
@@ -1228,9 +1285,9 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
12281285 * However, if we didn't have a callback promise outstanding, or it was
12291286 * outstanding on a different server, then it won't break it either...
12301287 */
1231- static int afs_dir_remove_link (struct dentry * dentry , struct key * key ,
1232- unsigned long d_version_before ,
1233- unsigned long d_version_after )
1288+ int afs_dir_remove_link (struct dentry * dentry , struct key * key ,
1289+ unsigned long d_version_before ,
1290+ unsigned long d_version_after )
12341291{
12351292 bool dir_valid ;
12361293 int ret = 0 ;
@@ -1277,6 +1334,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
12771334 struct afs_vnode * dvnode = AFS_FS_I (dir ), * vnode = NULL ;
12781335 struct key * key ;
12791336 unsigned long d_version = (unsigned long )dentry -> d_fsdata ;
1337+ bool need_rehash = false;
12801338 u64 data_version = dvnode -> status .data_version ;
12811339 int ret ;
12821340
@@ -1300,6 +1358,21 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
13001358 goto error_key ;
13011359 }
13021360
1361+ spin_lock (& dentry -> d_lock );
1362+ if (vnode && d_count (dentry ) > 1 ) {
1363+ spin_unlock (& dentry -> d_lock );
1364+ /* Start asynchronous writeout of the inode */
1365+ write_inode_now (d_inode (dentry ), 0 );
1366+ ret = afs_sillyrename (dvnode , vnode , dentry , key );
1367+ goto error_key ;
1368+ }
1369+ if (!d_unhashed (dentry )) {
1370+ /* Prevent a race with RCU lookup. */
1371+ __d_drop (dentry );
1372+ need_rehash = true;
1373+ }
1374+ spin_unlock (& dentry -> d_lock );
1375+
13031376 ret = - ERESTARTSYS ;
13041377 if (afs_begin_vnode_operation (& fc , dvnode , key )) {
13051378 while (afs_select_fileserver (& fc )) {
@@ -1331,6 +1404,9 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
13311404 afs_edit_dir_for_unlink );
13321405 }
13331406
1407+ if (need_rehash && ret < 0 && ret != - ENOENT )
1408+ d_rehash (dentry );
1409+
13341410error_key :
13351411 key_put (key );
13361412error :
@@ -1551,6 +1627,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
15511627{
15521628 struct afs_fs_cursor fc ;
15531629 struct afs_vnode * orig_dvnode , * new_dvnode , * vnode ;
1630+ struct dentry * tmp = NULL , * rehash = NULL ;
1631+ struct inode * new_inode ;
15541632 struct key * key ;
15551633 u64 orig_data_version , new_data_version ;
15561634 bool new_negative = d_is_negative (new_dentry );
@@ -1559,6 +1637,10 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
15591637 if (flags )
15601638 return - EINVAL ;
15611639
1640+ /* Don't allow silly-rename files be moved around. */
1641+ if (old_dentry -> d_flags & DCACHE_NFSFS_RENAMED )
1642+ return - EINVAL ;
1643+
15621644 vnode = AFS_FS_I (d_inode (old_dentry ));
15631645 orig_dvnode = AFS_FS_I (old_dir );
15641646 new_dvnode = AFS_FS_I (new_dir );
@@ -1577,12 +1659,48 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
15771659 goto error ;
15781660 }
15791661
1662+ /* For non-directories, check whether the target is busy and if so,
1663+ * make a copy of the dentry and then do a silly-rename. If the
1664+ * silly-rename succeeds, the copied dentry is hashed and becomes the
1665+ * new target.
1666+ */
1667+ if (d_is_positive (new_dentry ) && !d_is_dir (new_dentry )) {
1668+ /* To prevent any new references to the target during the
1669+ * rename, we unhash the dentry in advance.
1670+ */
1671+ if (!d_unhashed (new_dentry )) {
1672+ d_drop (new_dentry );
1673+ rehash = new_dentry ;
1674+ }
1675+
1676+ if (d_count (new_dentry ) > 2 ) {
1677+ /* copy the target dentry's name */
1678+ ret = - ENOMEM ;
1679+ tmp = d_alloc (new_dentry -> d_parent ,
1680+ & new_dentry -> d_name );
1681+ if (!tmp )
1682+ goto error_rehash ;
1683+
1684+ ret = afs_sillyrename (new_dvnode ,
1685+ AFS_FS_I (d_inode (new_dentry )),
1686+ new_dentry , key );
1687+ if (ret )
1688+ goto error_rehash ;
1689+
1690+ new_dentry = tmp ;
1691+ rehash = NULL ;
1692+ new_negative = true;
1693+ orig_data_version = orig_dvnode -> status .data_version ;
1694+ new_data_version = new_dvnode -> status .data_version ;
1695+ }
1696+ }
1697+
15801698 ret = - ERESTARTSYS ;
15811699 if (afs_begin_vnode_operation (& fc , orig_dvnode , key )) {
15821700 if (orig_dvnode != new_dvnode ) {
15831701 if (mutex_lock_interruptible_nested (& new_dvnode -> io_lock , 1 ) < 0 ) {
15841702 afs_end_vnode_operation (& fc );
1585- goto error_key ;
1703+ goto error_rehash ;
15861704 }
15871705 }
15881706 while (afs_select_fileserver (& fc )) {
@@ -1599,25 +1717,42 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
15991717 mutex_unlock (& new_dvnode -> io_lock );
16001718 ret = afs_end_vnode_operation (& fc );
16011719 if (ret < 0 )
1602- goto error_key ;
1720+ goto error_rehash ;
16031721 }
16041722
16051723 if (ret == 0 ) {
1724+ if (rehash )
1725+ d_rehash (rehash );
16061726 if (test_bit (AFS_VNODE_DIR_VALID , & orig_dvnode -> flags ))
16071727 afs_edit_dir_remove (orig_dvnode , & old_dentry -> d_name ,
1608- afs_edit_dir_for_rename );
1728+ afs_edit_dir_for_rename_0 );
16091729
16101730 if (!new_negative &&
16111731 test_bit (AFS_VNODE_DIR_VALID , & new_dvnode -> flags ))
16121732 afs_edit_dir_remove (new_dvnode , & new_dentry -> d_name ,
1613- afs_edit_dir_for_rename );
1733+ afs_edit_dir_for_rename_1 );
16141734
16151735 if (test_bit (AFS_VNODE_DIR_VALID , & new_dvnode -> flags ))
16161736 afs_edit_dir_add (new_dvnode , & new_dentry -> d_name ,
1617- & vnode -> fid , afs_edit_dir_for_rename );
1737+ & vnode -> fid , afs_edit_dir_for_rename_2 );
1738+
1739+ new_inode = d_inode (new_dentry );
1740+ if (new_inode ) {
1741+ spin_lock (& new_inode -> i_lock );
1742+ if (new_inode -> i_nlink > 0 )
1743+ drop_nlink (new_inode );
1744+ spin_unlock (& new_inode -> i_lock );
1745+ }
1746+ d_move (old_dentry , new_dentry );
1747+ goto error_tmp ;
16181748 }
16191749
1620- error_key :
1750+ error_rehash :
1751+ if (rehash )
1752+ d_rehash (rehash );
1753+ error_tmp :
1754+ if (tmp )
1755+ dput (tmp );
16211756 key_put (key );
16221757error :
16231758 _leave (" = %d" , ret );
0 commit comments