Commit 1daef0a868370c5a96d031b9202e3354bea060e6

Authored by Trond Myklebust
1 parent d5e66348bb

NFS: Clean up nfs_sb_active/nfs_sb_deactive

Instead of causing umount requests to block on server->active_wq while the
asynchronous sillyrename deletes are executing, we can use the sb->s_active
counter to obtain a reference to the super_block, and then release that
reference in nfs_async_unlink_release().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 5 changed files with 13 additions and 22 deletions Side-by-side Diff

... ... @@ -850,7 +850,6 @@
850 850 INIT_LIST_HEAD(&server->client_link);
851 851 INIT_LIST_HEAD(&server->master_link);
852 852  
853   - init_waitqueue_head(&server->active_wq);
854 853 atomic_set(&server->active, 0);
855 854  
856 855 server->io_stats = nfs_alloc_iostats();
... ... @@ -163,8 +163,8 @@
163 163  
164 164 extern int __init register_nfs_fs(void);
165 165 extern void __exit unregister_nfs_fs(void);
166   -extern void nfs_sb_active(struct nfs_server *server);
167   -extern void nfs_sb_deactive(struct nfs_server *server);
  166 +extern void nfs_sb_active(struct super_block *sb);
  167 +extern void nfs_sb_deactive(struct super_block *sb);
168 168  
169 169 /* namespace.c */
170 170 extern char *nfs_path(const char *base,
... ... @@ -209,7 +209,6 @@
209 209 static int nfs_xdev_get_sb(struct file_system_type *fs_type,
210 210 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
211 211 static void nfs_kill_super(struct super_block *);
212   -static void nfs_put_super(struct super_block *);
213 212 static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
214 213  
215 214 static struct file_system_type nfs_fs_type = {
... ... @@ -232,7 +231,6 @@
232 231 .alloc_inode = nfs_alloc_inode,
233 232 .destroy_inode = nfs_destroy_inode,
234 233 .write_inode = nfs_write_inode,
235   - .put_super = nfs_put_super,
236 234 .statfs = nfs_statfs,
237 235 .clear_inode = nfs_clear_inode,
238 236 .umount_begin = nfs_umount_begin,
239 237  
240 238  
241 239  
242 240  
... ... @@ -337,26 +335,20 @@
337 335 unregister_filesystem(&nfs_fs_type);
338 336 }
339 337  
340   -void nfs_sb_active(struct nfs_server *server)
  338 +void nfs_sb_active(struct super_block *sb)
341 339 {
342   - atomic_inc(&server->active);
343   -}
  340 + struct nfs_server *server = NFS_SB(sb);
344 341  
345   -void nfs_sb_deactive(struct nfs_server *server)
346   -{
347   - if (atomic_dec_and_test(&server->active))
348   - wake_up(&server->active_wq);
  342 + if (atomic_inc_return(&server->active) == 1)
  343 + atomic_inc(&sb->s_active);
349 344 }
350 345  
351   -static void nfs_put_super(struct super_block *sb)
  346 +void nfs_sb_deactive(struct super_block *sb)
352 347 {
353 348 struct nfs_server *server = NFS_SB(sb);
354   - /*
355   - * Make sure there are no outstanding ops to this server.
356   - * If so, wait for them to finish before allowing the
357   - * unmount to continue.
358   - */
359   - wait_event(server->active_wq, atomic_read(&server->active) == 0);
  349 +
  350 + if (atomic_dec_and_test(&server->active))
  351 + deactivate_super(sb);
360 352 }
361 353  
362 354 /*
... ... @@ -99,7 +99,7 @@
99 99  
100 100 nfs_dec_sillycount(data->dir);
101 101 nfs_free_unlinkdata(data);
102   - nfs_sb_deactive(NFS_SB(sb));
  102 + nfs_sb_deactive(sb);
103 103 }
104 104  
105 105 static const struct rpc_call_ops nfs_unlink_ops = {
... ... @@ -118,6 +118,7 @@
118 118 .rpc_message = &msg,
119 119 .callback_ops = &nfs_unlink_ops,
120 120 .callback_data = data,
  121 + .workqueue = nfsiod_workqueue,
121 122 .flags = RPC_TASK_ASYNC,
122 123 };
123 124 struct rpc_task *task;
... ... @@ -149,7 +150,7 @@
149 150 nfs_dec_sillycount(dir);
150 151 return 0;
151 152 }
152   - nfs_sb_active(NFS_SERVER(dir));
  153 + nfs_sb_active(dir->i_sb);
153 154 data->args.fh = NFS_FH(dir);
154 155 nfs_fattr_init(&data->res.dir_attr);
155 156  
include/linux/nfs_fs_sb.h
... ... @@ -119,7 +119,6 @@
119 119 void (*destroy)(struct nfs_server *);
120 120  
121 121 atomic_t active; /* Keep trace of any activity to this server */
122   - wait_queue_head_t active_wq; /* Wait for any activity to stop */
123 122  
124 123 /* mountd-related mount options */
125 124 struct sockaddr_storage mountd_address;