linux/fs/nfs/unlink.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/nfs/unlink.c
   3 *
   4 * nfs sillydelete handling
   5 *
   6 */
   7
   8#include <linux/slab.h>
   9#include <linux/string.h>
  10#include <linux/dcache.h>
  11#include <linux/sunrpc/sched.h>
  12#include <linux/sunrpc/clnt.h>
  13#include <linux/nfs_fs.h>
  14#include <linux/sched.h>
  15#include <linux/wait.h>
  16#include <linux/namei.h>
  17
  18#include "internal.h"
  19#include "nfs4_fs.h"
  20#include "iostat.h"
  21#include "delegation.h"
  22
  23#include "nfstrace.h"
  24
  25/**
  26 * nfs_free_unlinkdata - release data from a sillydelete operation.
  27 * @data: pointer to unlink structure.
  28 */
  29static void
  30nfs_free_unlinkdata(struct nfs_unlinkdata *data)
  31{
  32        iput(data->dir);
  33        put_rpccred(data->cred);
  34        kfree(data->args.name.name);
  35        kfree(data);
  36}
  37
  38#define NAME_ALLOC_LEN(len)     ((len+16) & ~15)
  39/**
  40 * nfs_copy_dname - copy dentry name to data structure
  41 * @dentry: pointer to dentry
  42 * @data: nfs_unlinkdata
  43 */
  44static int nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
  45{
  46        char            *str;
  47        int             len = dentry->d_name.len;
  48
  49        str = kmemdup(dentry->d_name.name, NAME_ALLOC_LEN(len), GFP_KERNEL);
  50        if (!str)
  51                return -ENOMEM;
  52        data->args.name.len = len;
  53        data->args.name.name = str;
  54        return 0;
  55}
  56
  57static void nfs_free_dname(struct nfs_unlinkdata *data)
  58{
  59        kfree(data->args.name.name);
  60        data->args.name.name = NULL;
  61        data->args.name.len = 0;
  62}
  63
  64static void nfs_dec_sillycount(struct inode *dir)
  65{
  66        struct nfs_inode *nfsi = NFS_I(dir);
  67        if (atomic_dec_return(&nfsi->silly_count) == 1)
  68                wake_up(&nfsi->waitqueue);
  69}
  70
  71/**
  72 * nfs_async_unlink_done - Sillydelete post-processing
  73 * @task: rpc_task of the sillydelete
  74 *
  75 * Do the directory attribute update.
  76 */
  77static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
  78{
  79        struct nfs_unlinkdata *data = calldata;
  80        struct inode *dir = data->dir;
  81
  82        trace_nfs_sillyrename_unlink(data, task->tk_status);
  83        if (!NFS_PROTO(dir)->unlink_done(task, dir))
  84                rpc_restart_call_prepare(task);
  85}
  86
  87/**
  88 * nfs_async_unlink_release - Release the sillydelete data.
  89 * @task: rpc_task of the sillydelete
  90 *
  91 * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
  92 * rpc_task would be freed too.
  93 */
  94static void nfs_async_unlink_release(void *calldata)
  95{
  96        struct nfs_unlinkdata   *data = calldata;
  97        struct super_block *sb = data->dir->i_sb;
  98
  99        nfs_dec_sillycount(data->dir);
 100        nfs_free_unlinkdata(data);
 101        nfs_sb_deactive(sb);
 102}
 103
 104static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
 105{
 106        struct nfs_unlinkdata *data = calldata;
 107        NFS_PROTO(data->dir)->unlink_rpc_prepare(task, data);
 108}
 109
 110static const struct rpc_call_ops nfs_unlink_ops = {
 111        .rpc_call_done = nfs_async_unlink_done,
 112        .rpc_release = nfs_async_unlink_release,
 113        .rpc_call_prepare = nfs_unlink_prepare,
 114};
 115
 116static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
 117{
 118        struct rpc_message msg = {
 119                .rpc_argp = &data->args,
 120                .rpc_resp = &data->res,
 121                .rpc_cred = data->cred,
 122        };
 123        struct rpc_task_setup task_setup_data = {
 124                .rpc_message = &msg,
 125                .callback_ops = &nfs_unlink_ops,
 126                .callback_data = data,
 127                .workqueue = nfsiod_workqueue,
 128                .flags = RPC_TASK_ASYNC,
 129        };
 130        struct rpc_task *task;
 131        struct dentry *alias;
 132
 133        alias = d_lookup(parent, &data->args.name);
 134        if (alias != NULL) {
 135                int ret;
 136                void *devname_garbage = NULL;
 137
 138                /*
 139                 * Hey, we raced with lookup... See if we need to transfer
 140                 * the sillyrename information to the aliased dentry.
 141                 */
 142                nfs_free_dname(data);
 143                ret = nfs_copy_dname(alias, data);
 144                spin_lock(&alias->d_lock);
 145                if (ret == 0 && alias->d_inode != NULL &&
 146                    !(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
 147                        devname_garbage = alias->d_fsdata;
 148                        alias->d_fsdata = data;
 149                        alias->d_flags |= DCACHE_NFSFS_RENAMED;
 150                        ret = 1;
 151                } else
 152                        ret = 0;
 153                spin_unlock(&alias->d_lock);
 154                nfs_dec_sillycount(dir);
 155                dput(alias);
 156                /*
 157                 * If we'd displaced old cached devname, free it.  At that
 158                 * point dentry is definitely not a root, so we won't need
 159                 * that anymore.
 160                 */
 161                kfree(devname_garbage);
 162                return ret;
 163        }
 164        data->dir = igrab(dir);
 165        if (!data->dir) {
 166                nfs_dec_sillycount(dir);
 167                return 0;
 168        }
 169        nfs_sb_active(dir->i_sb);
 170        data->args.fh = NFS_FH(dir);
 171        nfs_fattr_init(data->res.dir_attr);
 172
 173        NFS_PROTO(dir)->unlink_setup(&msg, dir);
 174
 175        task_setup_data.rpc_client = NFS_CLIENT(dir);
 176        task = rpc_run_task(&task_setup_data);
 177        if (!IS_ERR(task))
 178                rpc_put_task_async(task);
 179        return 1;
 180}
 181
 182static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
 183{
 184        struct dentry *parent;
 185        struct inode *dir;
 186        int ret = 0;
 187
 188
 189        parent = dget_parent(dentry);
 190        if (parent == NULL)
 191                goto out_free;
 192        dir = parent->d_inode;
 193        /* Non-exclusive lock protects against concurrent lookup() calls */
 194        spin_lock(&dir->i_lock);
 195        if (atomic_inc_not_zero(&NFS_I(dir)->silly_count) == 0) {
 196                /* Deferred delete */
 197                hlist_add_head(&data->list, &NFS_I(dir)->silly_list);
 198                spin_unlock(&dir->i_lock);
 199                ret = 1;
 200                goto out_dput;
 201        }
 202        spin_unlock(&dir->i_lock);
 203        ret = nfs_do_call_unlink(parent, dir, data);
 204out_dput:
 205        dput(parent);
 206out_free:
 207        return ret;
 208}
 209
 210void nfs_wait_on_sillyrename(struct dentry *dentry)
 211{
 212        struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
 213
 214        wait_event(nfsi->waitqueue, atomic_read(&nfsi->silly_count) <= 1);
 215}
 216
 217void nfs_block_sillyrename(struct dentry *dentry)
 218{
 219        struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
 220
 221        wait_event(nfsi->waitqueue, atomic_cmpxchg(&nfsi->silly_count, 1, 0) == 1);
 222}
 223
 224void nfs_unblock_sillyrename(struct dentry *dentry)
 225{
 226        struct inode *dir = dentry->d_inode;
 227        struct nfs_inode *nfsi = NFS_I(dir);
 228        struct nfs_unlinkdata *data;
 229
 230        atomic_inc(&nfsi->silly_count);
 231        spin_lock(&dir->i_lock);
 232        while (!hlist_empty(&nfsi->silly_list)) {
 233                if (!atomic_inc_not_zero(&nfsi->silly_count))
 234                        break;
 235                data = hlist_entry(nfsi->silly_list.first, struct nfs_unlinkdata, list);
 236                hlist_del(&data->list);
 237                spin_unlock(&dir->i_lock);
 238                if (nfs_do_call_unlink(dentry, dir, data) == 0)
 239                        nfs_free_unlinkdata(data);
 240                spin_lock(&dir->i_lock);
 241        }
 242        spin_unlock(&dir->i_lock);
 243}
 244
 245/**
 246 * nfs_async_unlink - asynchronous unlinking of a file
 247 * @dir: parent directory of dentry
 248 * @dentry: dentry to unlink
 249 */
 250static int
 251nfs_async_unlink(struct inode *dir, struct dentry *dentry)
 252{
 253        struct nfs_unlinkdata *data;
 254        int status = -ENOMEM;
 255        void *devname_garbage = NULL;
 256
 257        data = kzalloc(sizeof(*data), GFP_KERNEL);
 258        if (data == NULL)
 259                goto out;
 260
 261        data->cred = rpc_lookup_cred();
 262        if (IS_ERR(data->cred)) {
 263                status = PTR_ERR(data->cred);
 264                goto out_free;
 265        }
 266        data->res.dir_attr = &data->dir_attr;
 267
 268        status = -EBUSY;
 269        spin_lock(&dentry->d_lock);
 270        if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
 271                goto out_unlock;
 272        dentry->d_flags |= DCACHE_NFSFS_RENAMED;
 273        devname_garbage = dentry->d_fsdata;
 274        dentry->d_fsdata = data;
 275        spin_unlock(&dentry->d_lock);
 276        /*
 277         * If we'd displaced old cached devname, free it.  At that
 278         * point dentry is definitely not a root, so we won't need
 279         * that anymore.
 280         */
 281        kfree(devname_garbage);
 282        return 0;
 283out_unlock:
 284        spin_unlock(&dentry->d_lock);
 285        put_rpccred(data->cred);
 286out_free:
 287        kfree(data);
 288out:
 289        return status;
 290}
 291
 292/**
 293 * nfs_complete_unlink - Initialize completion of the sillydelete
 294 * @dentry: dentry to delete
 295 * @inode: inode
 296 *
 297 * Since we're most likely to be called by dentry_iput(), we
 298 * only use the dentry to find the sillydelete. We then copy the name
 299 * into the qstr.
 300 */
 301void
 302nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
 303{
 304        struct nfs_unlinkdata   *data = NULL;
 305
 306        spin_lock(&dentry->d_lock);
 307        if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
 308                dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
 309                data = dentry->d_fsdata;
 310                dentry->d_fsdata = NULL;
 311        }
 312        spin_unlock(&dentry->d_lock);
 313
 314        if (data != NULL && (NFS_STALE(inode) || !nfs_call_unlink(dentry, data)))
 315                nfs_free_unlinkdata(data);
 316}
 317
 318/* Cancel a queued async unlink. Called when a sillyrename run fails. */
 319static void
 320nfs_cancel_async_unlink(struct dentry *dentry)
 321{
 322        spin_lock(&dentry->d_lock);
 323        if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
 324                struct nfs_unlinkdata *data = dentry->d_fsdata;
 325
 326                dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
 327                dentry->d_fsdata = NULL;
 328                spin_unlock(&dentry->d_lock);
 329                nfs_free_unlinkdata(data);
 330                return;
 331        }
 332        spin_unlock(&dentry->d_lock);
 333}
 334
 335/**
 336 * nfs_async_rename_done - Sillyrename post-processing
 337 * @task: rpc_task of the sillyrename
 338 * @calldata: nfs_renamedata for the sillyrename
 339 *
 340 * Do the directory attribute updates and the d_move
 341 */
 342static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
 343{
 344        struct nfs_renamedata *data = calldata;
 345        struct inode *old_dir = data->old_dir;
 346        struct inode *new_dir = data->new_dir;
 347        struct dentry *old_dentry = data->old_dentry;
 348
 349        trace_nfs_sillyrename_rename(old_dir, old_dentry,
 350                        new_dir, data->new_dentry, task->tk_status);
 351        if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
 352                rpc_restart_call_prepare(task);
 353                return;
 354        }
 355
 356        if (task->tk_status != 0)
 357                nfs_cancel_async_unlink(old_dentry);
 358}
 359
 360/**
 361 * nfs_async_rename_release - Release the sillyrename data.
 362 * @calldata: the struct nfs_renamedata to be released
 363 */
 364static void nfs_async_rename_release(void *calldata)
 365{
 366        struct nfs_renamedata   *data = calldata;
 367        struct super_block *sb = data->old_dir->i_sb;
 368
 369        if (data->old_dentry->d_inode)
 370                nfs_mark_for_revalidate(data->old_dentry->d_inode);
 371
 372        dput(data->old_dentry);
 373        dput(data->new_dentry);
 374        iput(data->old_dir);
 375        iput(data->new_dir);
 376        nfs_sb_deactive(sb);
 377        put_rpccred(data->cred);
 378        kfree(data);
 379}
 380
 381static void nfs_rename_prepare(struct rpc_task *task, void *calldata)
 382{
 383        struct nfs_renamedata *data = calldata;
 384        NFS_PROTO(data->old_dir)->rename_rpc_prepare(task, data);
 385}
 386
 387static const struct rpc_call_ops nfs_rename_ops = {
 388        .rpc_call_done = nfs_async_rename_done,
 389        .rpc_release = nfs_async_rename_release,
 390        .rpc_call_prepare = nfs_rename_prepare,
 391};
 392
 393/**
 394 * nfs_async_rename - perform an asynchronous rename operation
 395 * @old_dir: directory that currently holds the dentry to be renamed
 396 * @new_dir: target directory for the rename
 397 * @old_dentry: original dentry to be renamed
 398 * @new_dentry: dentry to which the old_dentry should be renamed
 399 *
 400 * It's expected that valid references to the dentries and inodes are held
 401 */
 402static struct rpc_task *
 403nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
 404                 struct dentry *old_dentry, struct dentry *new_dentry)
 405{
 406        struct nfs_renamedata *data;
 407        struct rpc_message msg = { };
 408        struct rpc_task_setup task_setup_data = {
 409                .rpc_message = &msg,
 410                .callback_ops = &nfs_rename_ops,
 411                .workqueue = nfsiod_workqueue,
 412                .rpc_client = NFS_CLIENT(old_dir),
 413                .flags = RPC_TASK_ASYNC,
 414        };
 415
 416        data = kzalloc(sizeof(*data), GFP_KERNEL);
 417        if (data == NULL)
 418                return ERR_PTR(-ENOMEM);
 419        task_setup_data.callback_data = data;
 420
 421        data->cred = rpc_lookup_cred();
 422        if (IS_ERR(data->cred)) {
 423                struct rpc_task *task = ERR_CAST(data->cred);
 424                kfree(data);
 425                return task;
 426        }
 427
 428        msg.rpc_argp = &data->args;
 429        msg.rpc_resp = &data->res;
 430        msg.rpc_cred = data->cred;
 431
 432        /* set up nfs_renamedata */
 433        data->old_dir = old_dir;
 434        ihold(old_dir);
 435        data->new_dir = new_dir;
 436        ihold(new_dir);
 437        data->old_dentry = dget(old_dentry);
 438        data->new_dentry = dget(new_dentry);
 439        nfs_fattr_init(&data->old_fattr);
 440        nfs_fattr_init(&data->new_fattr);
 441
 442        /* set up nfs_renameargs */
 443        data->args.old_dir = NFS_FH(old_dir);
 444        data->args.old_name = &old_dentry->d_name;
 445        data->args.new_dir = NFS_FH(new_dir);
 446        data->args.new_name = &new_dentry->d_name;
 447
 448        /* set up nfs_renameres */
 449        data->res.old_fattr = &data->old_fattr;
 450        data->res.new_fattr = &data->new_fattr;
 451
 452        nfs_sb_active(old_dir->i_sb);
 453
 454        NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir);
 455
 456        return rpc_run_task(&task_setup_data);
 457}
 458
 459#define SILLYNAME_PREFIX ".nfs"
 460#define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
 461#define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
 462#define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
 463#define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
 464                SILLYNAME_FILEID_LEN + \
 465                SILLYNAME_COUNTER_LEN)
 466
 467/**
 468 * nfs_sillyrename - Perform a silly-rename of a dentry
 469 * @dir: inode of directory that contains dentry
 470 * @dentry: dentry to be sillyrenamed
 471 *
 472 * NFSv2/3 is stateless and the server doesn't know when the client is
 473 * holding a file open. To prevent application problems when a file is
 474 * unlinked while it's still open, the client performs a "silly-rename".
 475 * That is, it renames the file to a hidden file in the same directory,
 476 * and only performs the unlink once the last reference to it is put.
 477 *
 478 * The final cleanup is done during dentry_iput.
 479 *
 480 * (Note: NFSv4 is stateful, and has opens, so in theory an NFSv4 server
 481 * could take responsibility for keeping open files referenced.  The server
 482 * would also need to ensure that opened-but-deleted files were kept over
 483 * reboots.  However, we may not assume a server does so.  (RFC 5661
 484 * does provide an OPEN4_RESULT_PRESERVE_UNLINKED flag that a server can
 485 * use to advertise that it does this; some day we may take advantage of
 486 * it.))
 487 */
 488int
 489nfs_sillyrename(struct inode *dir, struct dentry *dentry)
 490{
 491        static unsigned int sillycounter;
 492        unsigned char silly[SILLYNAME_LEN + 1];
 493        unsigned long long fileid;
 494        struct dentry *sdentry;
 495        struct rpc_task *task;
 496        int            error = -EIO;
 497
 498        dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n",
 499                dentry->d_parent->d_name.name, dentry->d_name.name,
 500                d_count(dentry));
 501        nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
 502
 503        /*
 504         * We don't allow a dentry to be silly-renamed twice.
 505         */
 506        error = -EBUSY;
 507        if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
 508                goto out;
 509
 510        fileid = NFS_FILEID(dentry->d_inode);
 511
 512        /* Return delegation in anticipation of the rename */
 513        NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode);
 514
 515        sdentry = NULL;
 516        do {
 517                int slen;
 518                dput(sdentry);
 519                sillycounter++;
 520                slen = scnprintf(silly, sizeof(silly),
 521                                SILLYNAME_PREFIX "%0*llx%0*x",
 522                                SILLYNAME_FILEID_LEN, fileid,
 523                                SILLYNAME_COUNTER_LEN, sillycounter);
 524
 525                dfprintk(VFS, "NFS: trying to rename %s to %s\n",
 526                                dentry->d_name.name, silly);
 527
 528                sdentry = lookup_one_len(silly, dentry->d_parent, slen);
 529                /*
 530                 * N.B. Better to return EBUSY here ... it could be
 531                 * dangerous to delete the file while it's in use.
 532                 */
 533                if (IS_ERR(sdentry))
 534                        goto out;
 535        } while (sdentry->d_inode != NULL); /* need negative lookup */
 536
 537        /* queue unlink first. Can't do this from rpc_release as it
 538         * has to allocate memory
 539         */
 540        error = nfs_async_unlink(dir, dentry);
 541        if (error)
 542                goto out_dput;
 543
 544        /* populate unlinkdata with the right dname */
 545        error = nfs_copy_dname(sdentry,
 546                                (struct nfs_unlinkdata *)dentry->d_fsdata);
 547        if (error) {
 548                nfs_cancel_async_unlink(dentry);
 549                goto out_dput;
 550        }
 551
 552        /* run the rename task, undo unlink if it fails */
 553        task = nfs_async_rename(dir, dir, dentry, sdentry);
 554        if (IS_ERR(task)) {
 555                error = -EBUSY;
 556                nfs_cancel_async_unlink(dentry);
 557                goto out_dput;
 558        }
 559
 560        /* wait for the RPC task to complete, unless a SIGKILL intervenes */
 561        error = rpc_wait_for_completion_task(task);
 562        if (error == 0)
 563                error = task->tk_status;
 564        switch (error) {
 565        case 0:
 566                /* The rename succeeded */
 567                nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 568                d_move(dentry, sdentry);
 569                break;
 570        case -ERESTARTSYS:
 571                /* The result of the rename is unknown. Play it safe by
 572                 * forcing a new lookup */
 573                d_drop(dentry);
 574                d_drop(sdentry);
 575        }
 576        rpc_put_task(task);
 577out_dput:
 578        dput(sdentry);
 579out:
 580        return error;
 581}
 582