.. | .. |
---|
13 | 13 | #include <linux/sunrpc/clnt.h> |
---|
14 | 14 | #include <linux/nfs_fs.h> |
---|
15 | 15 | #include <linux/sched.h> |
---|
16 | | -#include <linux/swait.h> |
---|
| 16 | +#include <linux/wait.h> |
---|
17 | 17 | #include <linux/namei.h> |
---|
18 | 18 | #include <linux/fsnotify.h> |
---|
19 | 19 | |
---|
.. | .. |
---|
31 | 31 | static void |
---|
32 | 32 | nfs_free_unlinkdata(struct nfs_unlinkdata *data) |
---|
33 | 33 | { |
---|
34 | | - put_rpccred(data->cred); |
---|
| 34 | + put_cred(data->cred); |
---|
35 | 35 | kfree(data->args.name.name); |
---|
36 | 36 | kfree(data); |
---|
37 | 37 | } |
---|
.. | .. |
---|
39 | 39 | /** |
---|
40 | 40 | * nfs_async_unlink_done - Sillydelete post-processing |
---|
41 | 41 | * @task: rpc_task of the sillydelete |
---|
| 42 | + * @calldata: pointer to nfs_unlinkdata |
---|
42 | 43 | * |
---|
43 | 44 | * Do the directory attribute update. |
---|
44 | 45 | */ |
---|
.. | .. |
---|
52 | 53 | rpc_restart_call_prepare(task); |
---|
53 | 54 | } |
---|
54 | 55 | |
---|
55 | | -#ifdef CONFIG_PREEMPT_RT_BASE |
---|
56 | | -static void nfs_down_anon(struct semaphore *sema) |
---|
57 | | -{ |
---|
58 | | - down(sema); |
---|
59 | | -} |
---|
60 | | - |
---|
61 | | -static void nfs_up_anon(struct semaphore *sema) |
---|
62 | | -{ |
---|
63 | | - up(sema); |
---|
64 | | -} |
---|
65 | | - |
---|
66 | | -#else |
---|
67 | | -static void nfs_down_anon(struct rw_semaphore *rwsem) |
---|
68 | | -{ |
---|
69 | | - down_read_non_owner(rwsem); |
---|
70 | | -} |
---|
71 | | - |
---|
72 | | -static void nfs_up_anon(struct rw_semaphore *rwsem) |
---|
73 | | -{ |
---|
74 | | - up_read_non_owner(rwsem); |
---|
75 | | -} |
---|
76 | | -#endif |
---|
77 | | - |
---|
78 | 56 | /** |
---|
79 | 57 | * nfs_async_unlink_release - Release the sillydelete data. |
---|
80 | | - * @task: rpc_task of the sillydelete |
---|
| 58 | + * @calldata: struct nfs_unlinkdata to release |
---|
81 | 59 | * |
---|
82 | 60 | * We need to call nfs_put_unlinkdata as a 'tk_release' task since the |
---|
83 | 61 | * rpc_task would be freed too. |
---|
.. | .. |
---|
88 | 66 | struct dentry *dentry = data->dentry; |
---|
89 | 67 | struct super_block *sb = dentry->d_sb; |
---|
90 | 68 | |
---|
91 | | - nfs_up_anon(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem); |
---|
| 69 | + up_read_non_owner(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem); |
---|
92 | 70 | d_lookup_done(dentry); |
---|
93 | 71 | nfs_free_unlinkdata(data); |
---|
94 | 72 | dput(dentry); |
---|
.. | .. |
---|
120 | 98 | .callback_ops = &nfs_unlink_ops, |
---|
121 | 99 | .callback_data = data, |
---|
122 | 100 | .workqueue = nfsiod_workqueue, |
---|
123 | | - .flags = RPC_TASK_ASYNC, |
---|
| 101 | + .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF, |
---|
124 | 102 | }; |
---|
125 | 103 | struct rpc_task *task; |
---|
126 | 104 | struct inode *dir = d_inode(data->dentry->d_parent); |
---|
.. | .. |
---|
141 | 119 | struct inode *dir = d_inode(dentry->d_parent); |
---|
142 | 120 | struct dentry *alias; |
---|
143 | 121 | |
---|
144 | | - nfs_down_anon(&NFS_I(dir)->rmdir_sem); |
---|
| 122 | + down_read_non_owner(&NFS_I(dir)->rmdir_sem); |
---|
145 | 123 | alias = d_alloc_parallel(dentry->d_parent, &data->args.name, &data->wq); |
---|
146 | 124 | if (IS_ERR(alias)) { |
---|
147 | | - nfs_up_anon(&NFS_I(dir)->rmdir_sem); |
---|
| 125 | + up_read_non_owner(&NFS_I(dir)->rmdir_sem); |
---|
148 | 126 | return 0; |
---|
149 | 127 | } |
---|
150 | 128 | if (!d_in_lookup(alias)) { |
---|
.. | .. |
---|
166 | 144 | ret = 0; |
---|
167 | 145 | spin_unlock(&alias->d_lock); |
---|
168 | 146 | dput(alias); |
---|
169 | | - nfs_up_anon(&NFS_I(dir)->rmdir_sem); |
---|
| 147 | + up_read_non_owner(&NFS_I(dir)->rmdir_sem); |
---|
170 | 148 | /* |
---|
171 | 149 | * If we'd displaced old cached devname, free it. At that |
---|
172 | 150 | * point dentry is definitely not a root, so we won't need |
---|
.. | .. |
---|
182 | 160 | |
---|
183 | 161 | /** |
---|
184 | 162 | * nfs_async_unlink - asynchronous unlinking of a file |
---|
185 | | - * @dir: parent directory of dentry |
---|
186 | | - * @dentry: dentry to unlink |
---|
| 163 | + * @dentry: parent directory of dentry |
---|
| 164 | + * @name: name of dentry to unlink |
---|
187 | 165 | */ |
---|
188 | 166 | static int |
---|
189 | 167 | nfs_async_unlink(struct dentry *dentry, const struct qstr *name) |
---|
.. | .. |
---|
200 | 178 | goto out_free; |
---|
201 | 179 | data->args.name.len = name->len; |
---|
202 | 180 | |
---|
203 | | - data->cred = rpc_lookup_cred(); |
---|
204 | | - if (IS_ERR(data->cred)) { |
---|
205 | | - status = PTR_ERR(data->cred); |
---|
206 | | - goto out_free_name; |
---|
207 | | - } |
---|
| 181 | + data->cred = get_current_cred(); |
---|
208 | 182 | data->res.dir_attr = &data->dir_attr; |
---|
209 | | - init_swait_queue_head(&data->wq); |
---|
| 183 | + init_waitqueue_head(&data->wq); |
---|
210 | 184 | |
---|
211 | 185 | status = -EBUSY; |
---|
212 | 186 | spin_lock(&dentry->d_lock); |
---|
.. | .. |
---|
225 | 199 | return 0; |
---|
226 | 200 | out_unlock: |
---|
227 | 201 | spin_unlock(&dentry->d_lock); |
---|
228 | | - put_rpccred(data->cred); |
---|
229 | | -out_free_name: |
---|
| 202 | + put_cred(data->cred); |
---|
230 | 203 | kfree(data->args.name.name); |
---|
231 | 204 | out_free: |
---|
232 | 205 | kfree(data); |
---|
.. | .. |
---|
330 | 303 | iput(data->old_dir); |
---|
331 | 304 | iput(data->new_dir); |
---|
332 | 305 | nfs_sb_deactive(sb); |
---|
333 | | - put_rpccred(data->cred); |
---|
| 306 | + put_cred(data->cred); |
---|
334 | 307 | kfree(data); |
---|
335 | 308 | } |
---|
336 | 309 | |
---|
.. | .. |
---|
352 | 325 | * @new_dir: target directory for the rename |
---|
353 | 326 | * @old_dentry: original dentry to be renamed |
---|
354 | 327 | * @new_dentry: dentry to which the old_dentry should be renamed |
---|
| 328 | + * @complete: Function to run on successful completion |
---|
355 | 329 | * |
---|
356 | 330 | * It's expected that valid references to the dentries and inodes are held |
---|
357 | 331 | */ |
---|
.. | .. |
---|
367 | 341 | .callback_ops = &nfs_rename_ops, |
---|
368 | 342 | .workqueue = nfsiod_workqueue, |
---|
369 | 343 | .rpc_client = NFS_CLIENT(old_dir), |
---|
370 | | - .flags = RPC_TASK_ASYNC, |
---|
| 344 | + .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF, |
---|
371 | 345 | }; |
---|
372 | 346 | |
---|
373 | 347 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
---|
.. | .. |
---|
375 | 349 | return ERR_PTR(-ENOMEM); |
---|
376 | 350 | task_setup_data.callback_data = data; |
---|
377 | 351 | |
---|
378 | | - data->cred = rpc_lookup_cred(); |
---|
379 | | - if (IS_ERR(data->cred)) { |
---|
380 | | - struct rpc_task *task = ERR_CAST(data->cred); |
---|
381 | | - kfree(data); |
---|
382 | | - return task; |
---|
383 | | - } |
---|
| 352 | + data->cred = get_current_cred(); |
---|
384 | 353 | |
---|
385 | 354 | msg.rpc_argp = &data->args; |
---|
386 | 355 | msg.rpc_resp = &data->res; |
---|
.. | .. |
---|
427 | 396 | nfs_cancel_async_unlink(dentry); |
---|
428 | 397 | return; |
---|
429 | 398 | } |
---|
430 | | - |
---|
431 | | - /* |
---|
432 | | - * vfs_unlink and the like do not issue this when a file is |
---|
433 | | - * sillyrenamed, so do it here. |
---|
434 | | - */ |
---|
435 | | - fsnotify_nameremove(dentry, 0); |
---|
436 | 399 | } |
---|
437 | 400 | |
---|
438 | 401 | #define SILLYNAME_PREFIX ".nfs" |
---|