| .. | .. |
|---|
| 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" |
|---|