linux/fs/nfs/nfs42proc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
   4 */
   5#include <linux/fs.h>
   6#include <linux/sunrpc/sched.h>
   7#include <linux/nfs.h>
   8#include <linux/nfs3.h>
   9#include <linux/nfs4.h>
  10#include <linux/nfs_xdr.h>
  11#include <linux/nfs_fs.h>
  12#include "nfs4_fs.h"
  13#include "nfs42.h"
  14#include "iostat.h"
  15#include "pnfs.h"
  16#include "nfs4session.h"
  17#include "internal.h"
  18
  19#define NFSDBG_FACILITY NFSDBG_PROC
  20static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
  21
  22static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
  23                struct nfs_lock_context *lock, loff_t offset, loff_t len)
  24{
  25        struct inode *inode = file_inode(filep);
  26        struct nfs_server *server = NFS_SERVER(inode);
  27        struct nfs42_falloc_args args = {
  28                .falloc_fh      = NFS_FH(inode),
  29                .falloc_offset  = offset,
  30                .falloc_length  = len,
  31                .falloc_bitmask = server->cache_consistency_bitmask,
  32        };
  33        struct nfs42_falloc_res res = {
  34                .falloc_server  = server,
  35        };
  36        int status;
  37
  38        msg->rpc_argp = &args;
  39        msg->rpc_resp = &res;
  40
  41        status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context,
  42                        lock, FMODE_WRITE);
  43        if (status)
  44                return status;
  45
  46        res.falloc_fattr = nfs_alloc_fattr();
  47        if (!res.falloc_fattr)
  48                return -ENOMEM;
  49
  50        status = nfs4_call_sync(server->client, server, msg,
  51                                &args.seq_args, &res.seq_res, 0);
  52        if (status == 0)
  53                status = nfs_post_op_update_inode(inode, res.falloc_fattr);
  54
  55        kfree(res.falloc_fattr);
  56        return status;
  57}
  58
  59static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
  60                                loff_t offset, loff_t len)
  61{
  62        struct nfs_server *server = NFS_SERVER(file_inode(filep));
  63        struct nfs4_exception exception = { };
  64        struct nfs_lock_context *lock;
  65        int err;
  66
  67        lock = nfs_get_lock_context(nfs_file_open_context(filep));
  68        if (IS_ERR(lock))
  69                return PTR_ERR(lock);
  70
  71        exception.inode = file_inode(filep);
  72        exception.state = lock->open_context->state;
  73
  74        do {
  75                err = _nfs42_proc_fallocate(msg, filep, lock, offset, len);
  76                if (err == -ENOTSUPP) {
  77                        err = -EOPNOTSUPP;
  78                        break;
  79                }
  80                err = nfs4_handle_exception(server, err, &exception);
  81        } while (exception.retry);
  82
  83        nfs_put_lock_context(lock);
  84        return err;
  85}
  86
  87int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
  88{
  89        struct rpc_message msg = {
  90                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
  91        };
  92        struct inode *inode = file_inode(filep);
  93        int err;
  94
  95        if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
  96                return -EOPNOTSUPP;
  97
  98        inode_lock(inode);
  99
 100        err = nfs42_proc_fallocate(&msg, filep, offset, len);
 101        if (err == -EOPNOTSUPP)
 102                NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
 103
 104        inode_unlock(inode);
 105        return err;
 106}
 107
 108int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
 109{
 110        struct rpc_message msg = {
 111                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
 112        };
 113        struct inode *inode = file_inode(filep);
 114        int err;
 115
 116        if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
 117                return -EOPNOTSUPP;
 118
 119        inode_lock(inode);
 120        err = nfs_sync_inode(inode);
 121        if (err)
 122                goto out_unlock;
 123
 124        err = nfs42_proc_fallocate(&msg, filep, offset, len);
 125        if (err == 0)
 126                truncate_pagecache_range(inode, offset, (offset + len) -1);
 127        if (err == -EOPNOTSUPP)
 128                NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
 129out_unlock:
 130        inode_unlock(inode);
 131        return err;
 132}
 133
 134static int handle_async_copy(struct nfs42_copy_res *res,
 135                             struct nfs_server *server,
 136                             struct file *src,
 137                             struct file *dst,
 138                             nfs4_stateid *src_stateid)
 139{
 140        struct nfs4_copy_state *copy, *tmp_copy;
 141        int status = NFS4_OK;
 142        bool found_pending = false;
 143        struct nfs_open_context *ctx = nfs_file_open_context(dst);
 144
 145        copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
 146        if (!copy)
 147                return -ENOMEM;
 148
 149        spin_lock(&server->nfs_client->cl_lock);
 150        list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids,
 151                                copies) {
 152                if (memcmp(&res->write_res.stateid, &tmp_copy->stateid,
 153                                NFS4_STATEID_SIZE))
 154                        continue;
 155                found_pending = true;
 156                list_del(&tmp_copy->copies);
 157                break;
 158        }
 159        if (found_pending) {
 160                spin_unlock(&server->nfs_client->cl_lock);
 161                kfree(copy);
 162                copy = tmp_copy;
 163                goto out;
 164        }
 165
 166        memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
 167        init_completion(&copy->completion);
 168        copy->parent_state = ctx->state;
 169
 170        list_add_tail(&copy->copies, &server->ss_copies);
 171        spin_unlock(&server->nfs_client->cl_lock);
 172
 173        status = wait_for_completion_interruptible(&copy->completion);
 174        spin_lock(&server->nfs_client->cl_lock);
 175        list_del_init(&copy->copies);
 176        spin_unlock(&server->nfs_client->cl_lock);
 177        if (status == -ERESTARTSYS) {
 178                goto out_cancel;
 179        } else if (copy->flags) {
 180                status = -EAGAIN;
 181                goto out_cancel;
 182        }
 183out:
 184        res->write_res.count = copy->count;
 185        memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));
 186        status = -copy->error;
 187
 188        kfree(copy);
 189        return status;
 190out_cancel:
 191        nfs42_do_offload_cancel_async(dst, &copy->stateid);
 192        kfree(copy);
 193        return status;
 194}
 195
 196static int process_copy_commit(struct file *dst, loff_t pos_dst,
 197                               struct nfs42_copy_res *res)
 198{
 199        struct nfs_commitres cres;
 200        int status = -ENOMEM;
 201
 202        cres.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
 203        if (!cres.verf)
 204                goto out;
 205
 206        status = nfs4_proc_commit(dst, pos_dst, res->write_res.count, &cres);
 207        if (status)
 208                goto out_free;
 209        if (nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
 210                                    &cres.verf->verifier)) {
 211                dprintk("commit verf differs from copy verf\n");
 212                status = -EAGAIN;
 213        }
 214out_free:
 215        kfree(cres.verf);
 216out:
 217        return status;
 218}
 219
 220static ssize_t _nfs42_proc_copy(struct file *src,
 221                                struct nfs_lock_context *src_lock,
 222                                struct file *dst,
 223                                struct nfs_lock_context *dst_lock,
 224                                struct nfs42_copy_args *args,
 225                                struct nfs42_copy_res *res)
 226{
 227        struct rpc_message msg = {
 228                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
 229                .rpc_argp = args,
 230                .rpc_resp = res,
 231        };
 232        struct inode *dst_inode = file_inode(dst);
 233        struct nfs_server *server = NFS_SERVER(dst_inode);
 234        loff_t pos_src = args->src_pos;
 235        loff_t pos_dst = args->dst_pos;
 236        size_t count = args->count;
 237        ssize_t status;
 238
 239        status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
 240                                     src_lock, FMODE_READ);
 241        if (status)
 242                return status;
 243
 244        status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
 245                        pos_src, pos_src + (loff_t)count - 1);
 246        if (status)
 247                return status;
 248
 249        status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
 250                                     dst_lock, FMODE_WRITE);
 251        if (status)
 252                return status;
 253
 254        status = nfs_sync_inode(dst_inode);
 255        if (status)
 256                return status;
 257
 258        res->commit_res.verf = NULL;
 259        if (args->sync) {
 260                res->commit_res.verf =
 261                        kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
 262                if (!res->commit_res.verf)
 263                        return -ENOMEM;
 264        }
 265        set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
 266                &dst_lock->open_context->state->flags);
 267
 268        status = nfs4_call_sync(server->client, server, &msg,
 269                                &args->seq_args, &res->seq_res, 0);
 270        if (status == -ENOTSUPP)
 271                server->caps &= ~NFS_CAP_COPY;
 272        if (status)
 273                goto out;
 274
 275        if (args->sync &&
 276                nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
 277                                    &res->commit_res.verf->verifier)) {
 278                status = -EAGAIN;
 279                goto out;
 280        }
 281
 282        if (!res->synchronous) {
 283                status = handle_async_copy(res, server, src, dst,
 284                                &args->src_stateid);
 285                if (status)
 286                        return status;
 287        }
 288
 289        if ((!res->synchronous || !args->sync) &&
 290                        res->write_res.verifier.committed != NFS_FILE_SYNC) {
 291                status = process_copy_commit(dst, pos_dst, res);
 292                if (status)
 293                        return status;
 294        }
 295
 296        truncate_pagecache_range(dst_inode, pos_dst,
 297                                 pos_dst + res->write_res.count);
 298
 299        status = res->write_res.count;
 300out:
 301        if (args->sync)
 302                kfree(res->commit_res.verf);
 303        return status;
 304}
 305
 306ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
 307                        struct file *dst, loff_t pos_dst,
 308                        size_t count)
 309{
 310        struct nfs_server *server = NFS_SERVER(file_inode(dst));
 311        struct nfs_lock_context *src_lock;
 312        struct nfs_lock_context *dst_lock;
 313        struct nfs42_copy_args args = {
 314                .src_fh         = NFS_FH(file_inode(src)),
 315                .src_pos        = pos_src,
 316                .dst_fh         = NFS_FH(file_inode(dst)),
 317                .dst_pos        = pos_dst,
 318                .count          = count,
 319                .sync           = false,
 320        };
 321        struct nfs42_copy_res res;
 322        struct nfs4_exception src_exception = {
 323                .inode          = file_inode(src),
 324                .stateid        = &args.src_stateid,
 325        };
 326        struct nfs4_exception dst_exception = {
 327                .inode          = file_inode(dst),
 328                .stateid        = &args.dst_stateid,
 329        };
 330        ssize_t err, err2;
 331
 332        src_lock = nfs_get_lock_context(nfs_file_open_context(src));
 333        if (IS_ERR(src_lock))
 334                return PTR_ERR(src_lock);
 335
 336        src_exception.state = src_lock->open_context->state;
 337
 338        dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
 339        if (IS_ERR(dst_lock)) {
 340                err = PTR_ERR(dst_lock);
 341                goto out_put_src_lock;
 342        }
 343
 344        dst_exception.state = dst_lock->open_context->state;
 345
 346        do {
 347                inode_lock(file_inode(dst));
 348                err = _nfs42_proc_copy(src, src_lock,
 349                                dst, dst_lock,
 350                                &args, &res);
 351                inode_unlock(file_inode(dst));
 352
 353                if (err >= 0)
 354                        break;
 355                if (err == -ENOTSUPP) {
 356                        err = -EOPNOTSUPP;
 357                        break;
 358                } else if (err == -EAGAIN) {
 359                        dst_exception.retry = 1;
 360                        continue;
 361                } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
 362                        args.sync = true;
 363                        dst_exception.retry = 1;
 364                        continue;
 365                }
 366
 367                err2 = nfs4_handle_exception(server, err, &src_exception);
 368                err  = nfs4_handle_exception(server, err, &dst_exception);
 369                if (!err)
 370                        err = err2;
 371        } while (src_exception.retry || dst_exception.retry);
 372
 373        nfs_put_lock_context(dst_lock);
 374out_put_src_lock:
 375        nfs_put_lock_context(src_lock);
 376        return err;
 377}
 378
 379struct nfs42_offloadcancel_data {
 380        struct nfs_server *seq_server;
 381        struct nfs42_offload_status_args args;
 382        struct nfs42_offload_status_res res;
 383};
 384
 385static void nfs42_offload_cancel_prepare(struct rpc_task *task, void *calldata)
 386{
 387        struct nfs42_offloadcancel_data *data = calldata;
 388
 389        nfs4_setup_sequence(data->seq_server->nfs_client,
 390                                &data->args.osa_seq_args,
 391                                &data->res.osr_seq_res, task);
 392}
 393
 394static void nfs42_offload_cancel_done(struct rpc_task *task, void *calldata)
 395{
 396        struct nfs42_offloadcancel_data *data = calldata;
 397
 398        nfs41_sequence_done(task, &data->res.osr_seq_res);
 399        if (task->tk_status &&
 400                nfs4_async_handle_error(task, data->seq_server, NULL,
 401                        NULL) == -EAGAIN)
 402                rpc_restart_call_prepare(task);
 403}
 404
 405static void nfs42_free_offloadcancel_data(void *data)
 406{
 407        kfree(data);
 408}
 409
 410static const struct rpc_call_ops nfs42_offload_cancel_ops = {
 411        .rpc_call_prepare = nfs42_offload_cancel_prepare,
 412        .rpc_call_done = nfs42_offload_cancel_done,
 413        .rpc_release = nfs42_free_offloadcancel_data,
 414};
 415
 416static int nfs42_do_offload_cancel_async(struct file *dst,
 417                                         nfs4_stateid *stateid)
 418{
 419        struct nfs_server *dst_server = NFS_SERVER(file_inode(dst));
 420        struct nfs42_offloadcancel_data *data = NULL;
 421        struct nfs_open_context *ctx = nfs_file_open_context(dst);
 422        struct rpc_task *task;
 423        struct rpc_message msg = {
 424                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OFFLOAD_CANCEL],
 425                .rpc_cred = ctx->cred,
 426        };
 427        struct rpc_task_setup task_setup_data = {
 428                .rpc_client = dst_server->client,
 429                .rpc_message = &msg,
 430                .callback_ops = &nfs42_offload_cancel_ops,
 431                .workqueue = nfsiod_workqueue,
 432                .flags = RPC_TASK_ASYNC,
 433        };
 434        int status;
 435
 436        if (!(dst_server->caps & NFS_CAP_OFFLOAD_CANCEL))
 437                return -EOPNOTSUPP;
 438
 439        data = kzalloc(sizeof(struct nfs42_offloadcancel_data), GFP_NOFS);
 440        if (data == NULL)
 441                return -ENOMEM;
 442
 443        data->seq_server = dst_server;
 444        data->args.osa_src_fh = NFS_FH(file_inode(dst));
 445        memcpy(&data->args.osa_stateid, stateid,
 446                sizeof(data->args.osa_stateid));
 447        msg.rpc_argp = &data->args;
 448        msg.rpc_resp = &data->res;
 449        task_setup_data.callback_data = data;
 450        nfs4_init_sequence(&data->args.osa_seq_args, &data->res.osr_seq_res,
 451                           1, 0);
 452        task = rpc_run_task(&task_setup_data);
 453        if (IS_ERR(task))
 454                return PTR_ERR(task);
 455        status = rpc_wait_for_completion_task(task);
 456        if (status == -ENOTSUPP)
 457                dst_server->caps &= ~NFS_CAP_OFFLOAD_CANCEL;
 458        rpc_put_task(task);
 459        return status;
 460}
 461
 462static loff_t _nfs42_proc_llseek(struct file *filep,
 463                struct nfs_lock_context *lock, loff_t offset, int whence)
 464{
 465        struct inode *inode = file_inode(filep);
 466        struct nfs42_seek_args args = {
 467                .sa_fh          = NFS_FH(inode),
 468                .sa_offset      = offset,
 469                .sa_what        = (whence == SEEK_HOLE) ?
 470                                        NFS4_CONTENT_HOLE : NFS4_CONTENT_DATA,
 471        };
 472        struct nfs42_seek_res res;
 473        struct rpc_message msg = {
 474                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEEK],
 475                .rpc_argp = &args,
 476                .rpc_resp = &res,
 477        };
 478        struct nfs_server *server = NFS_SERVER(inode);
 479        int status;
 480
 481        if (!nfs_server_capable(inode, NFS_CAP_SEEK))
 482                return -ENOTSUPP;
 483
 484        status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context,
 485                        lock, FMODE_READ);
 486        if (status)
 487                return status;
 488
 489        status = nfs_filemap_write_and_wait_range(inode->i_mapping,
 490                        offset, LLONG_MAX);
 491        if (status)
 492                return status;
 493
 494        status = nfs4_call_sync(server->client, server, &msg,
 495                                &args.seq_args, &res.seq_res, 0);
 496        if (status == -ENOTSUPP)
 497                server->caps &= ~NFS_CAP_SEEK;
 498        if (status)
 499                return status;
 500
 501        return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
 502}
 503
 504loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
 505{
 506        struct nfs_server *server = NFS_SERVER(file_inode(filep));
 507        struct nfs4_exception exception = { };
 508        struct nfs_lock_context *lock;
 509        loff_t err;
 510
 511        lock = nfs_get_lock_context(nfs_file_open_context(filep));
 512        if (IS_ERR(lock))
 513                return PTR_ERR(lock);
 514
 515        exception.inode = file_inode(filep);
 516        exception.state = lock->open_context->state;
 517
 518        do {
 519                err = _nfs42_proc_llseek(filep, lock, offset, whence);
 520                if (err >= 0)
 521                        break;
 522                if (err == -ENOTSUPP) {
 523                        err = -EOPNOTSUPP;
 524                        break;
 525                }
 526                err = nfs4_handle_exception(server, err, &exception);
 527        } while (exception.retry);
 528
 529        nfs_put_lock_context(lock);
 530        return err;
 531}
 532
 533
 534static void
 535nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
 536{
 537        struct nfs42_layoutstat_data *data = calldata;
 538        struct inode *inode = data->inode;
 539        struct nfs_server *server = NFS_SERVER(inode);
 540        struct pnfs_layout_hdr *lo;
 541
 542        spin_lock(&inode->i_lock);
 543        lo = NFS_I(inode)->layout;
 544        if (!pnfs_layout_is_valid(lo)) {
 545                spin_unlock(&inode->i_lock);
 546                rpc_exit(task, 0);
 547                return;
 548        }
 549        nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid);
 550        spin_unlock(&inode->i_lock);
 551        nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
 552                            &data->res.seq_res, task);
 553}
 554
 555static void
 556nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
 557{
 558        struct nfs42_layoutstat_data *data = calldata;
 559        struct inode *inode = data->inode;
 560        struct pnfs_layout_hdr *lo;
 561
 562        if (!nfs4_sequence_done(task, &data->res.seq_res))
 563                return;
 564
 565        switch (task->tk_status) {
 566        case 0:
 567                break;
 568        case -NFS4ERR_BADHANDLE:
 569        case -ESTALE:
 570                pnfs_destroy_layout(NFS_I(inode));
 571                break;
 572        case -NFS4ERR_EXPIRED:
 573        case -NFS4ERR_ADMIN_REVOKED:
 574        case -NFS4ERR_DELEG_REVOKED:
 575        case -NFS4ERR_STALE_STATEID:
 576        case -NFS4ERR_BAD_STATEID:
 577                spin_lock(&inode->i_lock);
 578                lo = NFS_I(inode)->layout;
 579                if (pnfs_layout_is_valid(lo) &&
 580                    nfs4_stateid_match(&data->args.stateid,
 581                                             &lo->plh_stateid)) {
 582                        LIST_HEAD(head);
 583
 584                        /*
 585                         * Mark the bad layout state as invalid, then retry
 586                         * with the current stateid.
 587                         */
 588                        pnfs_mark_layout_stateid_invalid(lo, &head);
 589                        spin_unlock(&inode->i_lock);
 590                        pnfs_free_lseg_list(&head);
 591                        nfs_commit_inode(inode, 0);
 592                } else
 593                        spin_unlock(&inode->i_lock);
 594                break;
 595        case -NFS4ERR_OLD_STATEID:
 596                spin_lock(&inode->i_lock);
 597                lo = NFS_I(inode)->layout;
 598                if (pnfs_layout_is_valid(lo) &&
 599                    nfs4_stateid_match_other(&data->args.stateid,
 600                                        &lo->plh_stateid)) {
 601                        /* Do we need to delay before resending? */
 602                        if (!nfs4_stateid_is_newer(&lo->plh_stateid,
 603                                                &data->args.stateid))
 604                                rpc_delay(task, HZ);
 605                        rpc_restart_call_prepare(task);
 606                }
 607                spin_unlock(&inode->i_lock);
 608                break;
 609        case -ENOTSUPP:
 610        case -EOPNOTSUPP:
 611                NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
 612        }
 613}
 614
 615static void
 616nfs42_layoutstat_release(void *calldata)
 617{
 618        struct nfs42_layoutstat_data *data = calldata;
 619        struct nfs42_layoutstat_devinfo *devinfo = data->args.devinfo;
 620        int i;
 621
 622        for (i = 0; i < data->args.num_dev; i++) {
 623                if (devinfo[i].ld_private.ops && devinfo[i].ld_private.ops->free)
 624                        devinfo[i].ld_private.ops->free(&devinfo[i].ld_private);
 625        }
 626
 627        pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
 628        smp_mb__before_atomic();
 629        clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags);
 630        smp_mb__after_atomic();
 631        nfs_iput_and_deactive(data->inode);
 632        kfree(data->args.devinfo);
 633        kfree(data);
 634}
 635
 636static const struct rpc_call_ops nfs42_layoutstat_ops = {
 637        .rpc_call_prepare = nfs42_layoutstat_prepare,
 638        .rpc_call_done = nfs42_layoutstat_done,
 639        .rpc_release = nfs42_layoutstat_release,
 640};
 641
 642int nfs42_proc_layoutstats_generic(struct nfs_server *server,
 643                                   struct nfs42_layoutstat_data *data)
 644{
 645        struct rpc_message msg = {
 646                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTSTATS],
 647                .rpc_argp = &data->args,
 648                .rpc_resp = &data->res,
 649        };
 650        struct rpc_task_setup task_setup = {
 651                .rpc_client = server->client,
 652                .rpc_message = &msg,
 653                .callback_ops = &nfs42_layoutstat_ops,
 654                .callback_data = data,
 655                .flags = RPC_TASK_ASYNC,
 656        };
 657        struct rpc_task *task;
 658
 659        data->inode = nfs_igrab_and_active(data->args.inode);
 660        if (!data->inode) {
 661                nfs42_layoutstat_release(data);
 662                return -EAGAIN;
 663        }
 664        nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0, 0);
 665        task = rpc_run_task(&task_setup);
 666        if (IS_ERR(task))
 667                return PTR_ERR(task);
 668        rpc_put_task(task);
 669        return 0;
 670}
 671
 672static struct nfs42_layouterror_data *
 673nfs42_alloc_layouterror_data(struct pnfs_layout_segment *lseg, gfp_t gfp_flags)
 674{
 675        struct nfs42_layouterror_data *data;
 676        struct inode *inode = lseg->pls_layout->plh_inode;
 677
 678        data = kzalloc(sizeof(*data), gfp_flags);
 679        if (data) {
 680                data->args.inode = data->inode = nfs_igrab_and_active(inode);
 681                if (data->inode) {
 682                        data->lseg = pnfs_get_lseg(lseg);
 683                        if (data->lseg)
 684                                return data;
 685                        nfs_iput_and_deactive(data->inode);
 686                }
 687                kfree(data);
 688        }
 689        return NULL;
 690}
 691
 692static void
 693nfs42_free_layouterror_data(struct nfs42_layouterror_data *data)
 694{
 695        pnfs_put_lseg(data->lseg);
 696        nfs_iput_and_deactive(data->inode);
 697        kfree(data);
 698}
 699
 700static void
 701nfs42_layouterror_prepare(struct rpc_task *task, void *calldata)
 702{
 703        struct nfs42_layouterror_data *data = calldata;
 704        struct inode *inode = data->inode;
 705        struct nfs_server *server = NFS_SERVER(inode);
 706        struct pnfs_layout_hdr *lo = data->lseg->pls_layout;
 707        unsigned i;
 708
 709        spin_lock(&inode->i_lock);
 710        if (!pnfs_layout_is_valid(lo)) {
 711                spin_unlock(&inode->i_lock);
 712                rpc_exit(task, 0);
 713                return;
 714        }
 715        for (i = 0; i < data->args.num_errors; i++)
 716                nfs4_stateid_copy(&data->args.errors[i].stateid,
 717                                &lo->plh_stateid);
 718        spin_unlock(&inode->i_lock);
 719        nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
 720                            &data->res.seq_res, task);
 721}
 722
 723static void
 724nfs42_layouterror_done(struct rpc_task *task, void *calldata)
 725{
 726        struct nfs42_layouterror_data *data = calldata;
 727        struct inode *inode = data->inode;
 728        struct pnfs_layout_hdr *lo = data->lseg->pls_layout;
 729
 730        if (!nfs4_sequence_done(task, &data->res.seq_res))
 731                return;
 732
 733        switch (task->tk_status) {
 734        case 0:
 735                break;
 736        case -NFS4ERR_BADHANDLE:
 737        case -ESTALE:
 738                pnfs_destroy_layout(NFS_I(inode));
 739                break;
 740        case -NFS4ERR_EXPIRED:
 741        case -NFS4ERR_ADMIN_REVOKED:
 742        case -NFS4ERR_DELEG_REVOKED:
 743        case -NFS4ERR_STALE_STATEID:
 744        case -NFS4ERR_BAD_STATEID:
 745                spin_lock(&inode->i_lock);
 746                if (pnfs_layout_is_valid(lo) &&
 747                    nfs4_stateid_match(&data->args.errors[0].stateid,
 748                                             &lo->plh_stateid)) {
 749                        LIST_HEAD(head);
 750
 751                        /*
 752                         * Mark the bad layout state as invalid, then retry
 753                         * with the current stateid.
 754                         */
 755                        pnfs_mark_layout_stateid_invalid(lo, &head);
 756                        spin_unlock(&inode->i_lock);
 757                        pnfs_free_lseg_list(&head);
 758                        nfs_commit_inode(inode, 0);
 759                } else
 760                        spin_unlock(&inode->i_lock);
 761                break;
 762        case -NFS4ERR_OLD_STATEID:
 763                spin_lock(&inode->i_lock);
 764                if (pnfs_layout_is_valid(lo) &&
 765                    nfs4_stateid_match_other(&data->args.errors[0].stateid,
 766                                        &lo->plh_stateid)) {
 767                        /* Do we need to delay before resending? */
 768                        if (!nfs4_stateid_is_newer(&lo->plh_stateid,
 769                                                &data->args.errors[0].stateid))
 770                                rpc_delay(task, HZ);
 771                        rpc_restart_call_prepare(task);
 772                }
 773                spin_unlock(&inode->i_lock);
 774                break;
 775        case -ENOTSUPP:
 776        case -EOPNOTSUPP:
 777                NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTERROR;
 778        }
 779}
 780
 781static void
 782nfs42_layouterror_release(void *calldata)
 783{
 784        struct nfs42_layouterror_data *data = calldata;
 785
 786        nfs42_free_layouterror_data(data);
 787}
 788
 789static const struct rpc_call_ops nfs42_layouterror_ops = {
 790        .rpc_call_prepare = nfs42_layouterror_prepare,
 791        .rpc_call_done = nfs42_layouterror_done,
 792        .rpc_release = nfs42_layouterror_release,
 793};
 794
 795int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,
 796                const struct nfs42_layout_error *errors, size_t n)
 797{
 798        struct inode *inode = lseg->pls_layout->plh_inode;
 799        struct nfs42_layouterror_data *data;
 800        struct rpc_task *task;
 801        struct rpc_message msg = {
 802                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTERROR],
 803        };
 804        struct rpc_task_setup task_setup = {
 805                .rpc_message = &msg,
 806                .callback_ops = &nfs42_layouterror_ops,
 807                .flags = RPC_TASK_ASYNC,
 808        };
 809        unsigned int i;
 810
 811        if (!nfs_server_capable(inode, NFS_CAP_LAYOUTERROR))
 812                return -EOPNOTSUPP;
 813        if (n > NFS42_LAYOUTERROR_MAX)
 814                return -EINVAL;
 815        data = nfs42_alloc_layouterror_data(lseg, GFP_NOFS);
 816        if (!data)
 817                return -ENOMEM;
 818        for (i = 0; i < n; i++) {
 819                data->args.errors[i] = errors[i];
 820                data->args.num_errors++;
 821                data->res.num_errors++;
 822        }
 823        msg.rpc_argp = &data->args;
 824        msg.rpc_resp = &data->res;
 825        task_setup.callback_data = data;
 826        task_setup.rpc_client = NFS_SERVER(inode)->client;
 827        nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0, 0);
 828        task = rpc_run_task(&task_setup);
 829        if (IS_ERR(task))
 830                return PTR_ERR(task);
 831        rpc_put_task(task);
 832        return 0;
 833}
 834EXPORT_SYMBOL_GPL(nfs42_proc_layouterror);
 835
 836static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
 837                struct file *dst_f, struct nfs_lock_context *src_lock,
 838                struct nfs_lock_context *dst_lock, loff_t src_offset,
 839                loff_t dst_offset, loff_t count)
 840{
 841        struct inode *src_inode = file_inode(src_f);
 842        struct inode *dst_inode = file_inode(dst_f);
 843        struct nfs_server *server = NFS_SERVER(dst_inode);
 844        struct nfs42_clone_args args = {
 845                .src_fh = NFS_FH(src_inode),
 846                .dst_fh = NFS_FH(dst_inode),
 847                .src_offset = src_offset,
 848                .dst_offset = dst_offset,
 849                .count = count,
 850                .dst_bitmask = server->cache_consistency_bitmask,
 851        };
 852        struct nfs42_clone_res res = {
 853                .server = server,
 854        };
 855        int status;
 856
 857        msg->rpc_argp = &args;
 858        msg->rpc_resp = &res;
 859
 860        status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
 861                        src_lock, FMODE_READ);
 862        if (status)
 863                return status;
 864
 865        status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
 866                        dst_lock, FMODE_WRITE);
 867        if (status)
 868                return status;
 869
 870        res.dst_fattr = nfs_alloc_fattr();
 871        if (!res.dst_fattr)
 872                return -ENOMEM;
 873
 874        status = nfs4_call_sync(server->client, server, msg,
 875                                &args.seq_args, &res.seq_res, 0);
 876        if (status == 0)
 877                status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
 878
 879        kfree(res.dst_fattr);
 880        return status;
 881}
 882
 883int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
 884                     loff_t src_offset, loff_t dst_offset, loff_t count)
 885{
 886        struct rpc_message msg = {
 887                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE],
 888        };
 889        struct inode *inode = file_inode(src_f);
 890        struct nfs_server *server = NFS_SERVER(file_inode(src_f));
 891        struct nfs_lock_context *src_lock;
 892        struct nfs_lock_context *dst_lock;
 893        struct nfs4_exception src_exception = { };
 894        struct nfs4_exception dst_exception = { };
 895        int err, err2;
 896
 897        if (!nfs_server_capable(inode, NFS_CAP_CLONE))
 898                return -EOPNOTSUPP;
 899
 900        src_lock = nfs_get_lock_context(nfs_file_open_context(src_f));
 901        if (IS_ERR(src_lock))
 902                return PTR_ERR(src_lock);
 903
 904        src_exception.inode = file_inode(src_f);
 905        src_exception.state = src_lock->open_context->state;
 906
 907        dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f));
 908        if (IS_ERR(dst_lock)) {
 909                err = PTR_ERR(dst_lock);
 910                goto out_put_src_lock;
 911        }
 912
 913        dst_exception.inode = file_inode(dst_f);
 914        dst_exception.state = dst_lock->open_context->state;
 915
 916        do {
 917                err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock,
 918                                        src_offset, dst_offset, count);
 919                if (err == -ENOTSUPP || err == -EOPNOTSUPP) {
 920                        NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE;
 921                        err = -EOPNOTSUPP;
 922                        break;
 923                }
 924
 925                err2 = nfs4_handle_exception(server, err, &src_exception);
 926                err = nfs4_handle_exception(server, err, &dst_exception);
 927                if (!err)
 928                        err = err2;
 929        } while (src_exception.retry || dst_exception.retry);
 930
 931        nfs_put_lock_context(dst_lock);
 932out_put_src_lock:
 933        nfs_put_lock_context(src_lock);
 934        return err;
 935}
 936