linux-bk/fs/afs/fsclient.c
<<
>>
Prefs
   1/* fsclient.c: AFS File Server client stubs
   2 *
   3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/sched.h>
  14#include <rxrpc/rxrpc.h>
  15#include <rxrpc/transport.h>
  16#include <rxrpc/connection.h>
  17#include <rxrpc/call.h>
  18#include "fsclient.h"
  19#include "cmservice.h"
  20#include "vnode.h"
  21#include "server.h"
  22#include "errors.h"
  23#include "internal.h"
  24
  25#define FSFETCHSTATUS           132     /* AFS Fetch file status */
  26#define FSFETCHDATA             130     /* AFS Fetch file data */
  27#define FSGIVEUPCALLBACKS       147     /* AFS Discard callback promises */
  28#define FSGETVOLUMEINFO         148     /* AFS Get root volume information */
  29#define FSGETROOTVOLUME         151     /* AFS Get root volume name */
  30#define FSLOOKUP                161     /* AFS lookup file in directory */
  31
  32/*****************************************************************************/
  33/*
  34 * map afs abort codes to/from Linux error codes
  35 * - called with call->lock held
  36 */
  37static void afs_rxfs_aemap(struct rxrpc_call *call)
  38{
  39        switch (call->app_err_state) {
  40        case RXRPC_ESTATE_LOCAL_ABORT:
  41                call->app_abort_code = -call->app_errno;
  42                break;
  43        case RXRPC_ESTATE_PEER_ABORT:
  44                call->app_errno = afs_abort_to_error(call->app_abort_code);
  45                break;
  46        default:
  47                break;
  48        }
  49} /* end afs_rxfs_aemap() */
  50
  51/*****************************************************************************/
  52/*
  53 * get the root volume name from a fileserver
  54 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
  55 */
  56#if 0
  57int afs_rxfs_get_root_volume(struct afs_server *server,
  58                             char *buf, size_t *buflen)
  59{
  60        struct rxrpc_connection *conn;
  61        struct rxrpc_call *call;
  62        struct kvec piov[2];
  63        size_t sent;
  64        int ret;
  65        u32 param[1];
  66
  67        DECLARE_WAITQUEUE(myself, current);
  68
  69        kenter("%p,%p,%u",server, buf, *buflen);
  70
  71        /* get hold of the fileserver connection */
  72        ret = afs_server_get_fsconn(server, &conn);
  73        if (ret < 0)
  74                goto out;
  75
  76        /* create a call through that connection */
  77        ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
  78        if (ret < 0) {
  79                printk("kAFS: Unable to create call: %d\n", ret);
  80                goto out_put_conn;
  81        }
  82        call->app_opcode = FSGETROOTVOLUME;
  83
  84        /* we want to get event notifications from the call */
  85        add_wait_queue(&call->waitq, &myself);
  86
  87        /* marshall the parameters */
  88        param[0] = htonl(FSGETROOTVOLUME);
  89
  90        piov[0].iov_len = sizeof(param);
  91        piov[0].iov_base = param;
  92
  93        /* send the parameters to the server */
  94        ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
  95                                    0, &sent);
  96        if (ret < 0)
  97                goto abort;
  98
  99        /* wait for the reply to completely arrive */
 100        for (;;) {
 101                set_current_state(TASK_INTERRUPTIBLE);
 102                if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
 103                    signal_pending(current))
 104                        break;
 105                schedule();
 106        }
 107        set_current_state(TASK_RUNNING);
 108
 109        ret = -EINTR;
 110        if (signal_pending(current))
 111                goto abort;
 112
 113        switch (call->app_call_state) {
 114        case RXRPC_CSTATE_ERROR:
 115                ret = call->app_errno;
 116                kdebug("Got Error: %d", ret);
 117                goto out_unwait;
 118
 119        case RXRPC_CSTATE_CLNT_GOT_REPLY:
 120                /* read the reply */
 121                kdebug("Got Reply: qty=%d", call->app_ready_qty);
 122
 123                ret = -EBADMSG;
 124                if (call->app_ready_qty <= 4)
 125                        goto abort;
 126
 127                ret = rxrpc_call_read_data(call, NULL, call->app_ready_qty, 0);
 128                if (ret < 0)
 129                        goto abort;
 130
 131#if 0
 132                /* unmarshall the reply */
 133                bp = buffer;
 134                for (loop = 0; loop < 65; loop++)
 135                        entry->name[loop] = ntohl(*bp++);
 136                entry->name[64] = 0;
 137
 138                entry->type = ntohl(*bp++);
 139                entry->num_servers = ntohl(*bp++);
 140
 141                for (loop = 0; loop < 8; loop++)
 142                        entry->servers[loop].addr.s_addr = *bp++;
 143
 144                for (loop = 0; loop < 8; loop++)
 145                        entry->servers[loop].partition = ntohl(*bp++);
 146
 147                for (loop = 0; loop < 8; loop++)
 148                        entry->servers[loop].flags = ntohl(*bp++);
 149
 150                for (loop = 0; loop < 3; loop++)
 151                        entry->volume_ids[loop] = ntohl(*bp++);
 152
 153                entry->clone_id = ntohl(*bp++);
 154                entry->flags = ntohl(*bp);
 155#endif
 156
 157                /* success */
 158                ret = 0;
 159                goto out_unwait;
 160
 161        default:
 162                BUG();
 163        }
 164
 165 abort:
 166        set_current_state(TASK_UNINTERRUPTIBLE);
 167        rxrpc_call_abort(call, ret);
 168        schedule();
 169 out_unwait:
 170        set_current_state(TASK_RUNNING);
 171        remove_wait_queue(&call->waitq, &myself);
 172        rxrpc_put_call(call);
 173 out_put_conn:
 174        afs_server_release_fsconn(server, conn);
 175 out:
 176        kleave("");
 177        return ret;
 178} /* end afs_rxfs_get_root_volume() */
 179#endif
 180
 181/*****************************************************************************/
 182/*
 183 * get information about a volume
 184 */
 185#if 0
 186int afs_rxfs_get_volume_info(struct afs_server *server,
 187                             const char *name,
 188                             struct afs_volume_info *vinfo)
 189{
 190        struct rxrpc_connection *conn;
 191        struct rxrpc_call *call;
 192        struct kvec piov[3];
 193        size_t sent;
 194        int ret;
 195        u32 param[2], *bp, zero;
 196
 197        DECLARE_WAITQUEUE(myself, current);
 198
 199        _enter("%p,%s,%p", server, name, vinfo);
 200
 201        /* get hold of the fileserver connection */
 202        ret = afs_server_get_fsconn(server, &conn);
 203        if (ret < 0)
 204                goto out;
 205
 206        /* create a call through that connection */
 207        ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
 208        if (ret < 0) {
 209                printk("kAFS: Unable to create call: %d\n", ret);
 210                goto out_put_conn;
 211        }
 212        call->app_opcode = FSGETVOLUMEINFO;
 213
 214        /* we want to get event notifications from the call */
 215        add_wait_queue(&call->waitq, &myself);
 216
 217        /* marshall the parameters */
 218        piov[1].iov_len = strlen(name);
 219        piov[1].iov_base = (char *) name;
 220
 221        zero = 0;
 222        piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
 223        piov[2].iov_base = &zero;
 224
 225        param[0] = htonl(FSGETVOLUMEINFO);
 226        param[1] = htonl(piov[1].iov_len);
 227
 228        piov[0].iov_len = sizeof(param);
 229        piov[0].iov_base = param;
 230
 231        /* send the parameters to the server */
 232        ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
 233                                    0, &sent);
 234        if (ret < 0)
 235                goto abort;
 236
 237        /* wait for the reply to completely arrive */
 238        bp = rxrpc_call_alloc_scratch(call, 64);
 239
 240        ret = rxrpc_call_read_data(call, bp, 64,
 241                                   RXRPC_CALL_READ_BLOCK |
 242                                   RXRPC_CALL_READ_ALL);
 243        if (ret < 0) {
 244                if (ret == -ECONNABORTED) {
 245                        ret = call->app_errno;
 246                        goto out_unwait;
 247                }
 248                goto abort;
 249        }
 250
 251        /* unmarshall the reply */
 252        vinfo->vid = ntohl(*bp++);
 253        vinfo->type = ntohl(*bp++);
 254
 255        vinfo->type_vids[0] = ntohl(*bp++);
 256        vinfo->type_vids[1] = ntohl(*bp++);
 257        vinfo->type_vids[2] = ntohl(*bp++);
 258        vinfo->type_vids[3] = ntohl(*bp++);
 259        vinfo->type_vids[4] = ntohl(*bp++);
 260
 261        vinfo->nservers = ntohl(*bp++);
 262        vinfo->servers[0].addr.s_addr = *bp++;
 263        vinfo->servers[1].addr.s_addr = *bp++;
 264        vinfo->servers[2].addr.s_addr = *bp++;
 265        vinfo->servers[3].addr.s_addr = *bp++;
 266        vinfo->servers[4].addr.s_addr = *bp++;
 267        vinfo->servers[5].addr.s_addr = *bp++;
 268        vinfo->servers[6].addr.s_addr = *bp++;
 269        vinfo->servers[7].addr.s_addr = *bp++;
 270
 271        ret = -EBADMSG;
 272        if (vinfo->nservers > 8)
 273                goto abort;
 274
 275        /* success */
 276        ret = 0;
 277
 278 out_unwait:
 279        set_current_state(TASK_RUNNING);
 280        remove_wait_queue(&call->waitq, &myself);
 281        rxrpc_put_call(call);
 282 out_put_conn:
 283        afs_server_release_fsconn(server, conn);
 284 out:
 285        _leave("");
 286        return ret;
 287
 288 abort:
 289        set_current_state(TASK_UNINTERRUPTIBLE);
 290        rxrpc_call_abort(call, ret);
 291        schedule();
 292        goto out_unwait;
 293
 294} /* end afs_rxfs_get_volume_info() */
 295#endif
 296
 297/*****************************************************************************/
 298/*
 299 * fetch the status information for a file
 300 */
 301int afs_rxfs_fetch_file_status(struct afs_server *server,
 302                               struct afs_vnode *vnode,
 303                               struct afs_volsync *volsync)
 304{
 305        struct afs_server_callslot callslot;
 306        struct rxrpc_call *call;
 307        struct kvec piov[1];
 308        size_t sent;
 309        int ret;
 310        __be32 *bp;
 311
 312        DECLARE_WAITQUEUE(myself, current);
 313
 314        _enter("%p,{%u,%u,%u}",
 315               server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
 316
 317        /* get hold of the fileserver connection */
 318        ret = afs_server_request_callslot(server, &callslot);
 319        if (ret < 0)
 320                goto out;
 321
 322        /* create a call through that connection */
 323        ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap,
 324                                &call);
 325        if (ret < 0) {
 326                printk("kAFS: Unable to create call: %d\n", ret);
 327                goto out_put_conn;
 328        }
 329        call->app_opcode = FSFETCHSTATUS;
 330
 331        /* we want to get event notifications from the call */
 332        add_wait_queue(&call->waitq, &myself);
 333
 334        /* marshall the parameters */
 335        bp = rxrpc_call_alloc_scratch(call, 16);
 336        bp[0] = htonl(FSFETCHSTATUS);
 337        bp[1] = htonl(vnode->fid.vid);
 338        bp[2] = htonl(vnode->fid.vnode);
 339        bp[3] = htonl(vnode->fid.unique);
 340
 341        piov[0].iov_len = 16;
 342        piov[0].iov_base = bp;
 343
 344        /* send the parameters to the server */
 345        ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
 346                                    0, &sent);
 347        if (ret < 0)
 348                goto abort;
 349
 350        /* wait for the reply to completely arrive */
 351        bp = rxrpc_call_alloc_scratch(call, 120);
 352
 353        ret = rxrpc_call_read_data(call, bp, 120,
 354                                   RXRPC_CALL_READ_BLOCK |
 355                                   RXRPC_CALL_READ_ALL);
 356        if (ret < 0) {
 357                if (ret == -ECONNABORTED) {
 358                        ret = call->app_errno;
 359                        goto out_unwait;
 360                }
 361                goto abort;
 362        }
 363
 364        /* unmarshall the reply */
 365        vnode->status.if_version        = ntohl(*bp++);
 366        vnode->status.type              = ntohl(*bp++);
 367        vnode->status.nlink             = ntohl(*bp++);
 368        vnode->status.size              = ntohl(*bp++);
 369        vnode->status.version           = ntohl(*bp++);
 370        vnode->status.author            = ntohl(*bp++);
 371        vnode->status.owner             = ntohl(*bp++);
 372        vnode->status.caller_access     = ntohl(*bp++);
 373        vnode->status.anon_access       = ntohl(*bp++);
 374        vnode->status.mode              = ntohl(*bp++);
 375        vnode->status.parent.vid        = vnode->fid.vid;
 376        vnode->status.parent.vnode      = ntohl(*bp++);
 377        vnode->status.parent.unique     = ntohl(*bp++);
 378        bp++; /* seg size */
 379        vnode->status.mtime_client      = ntohl(*bp++);
 380        vnode->status.mtime_server      = ntohl(*bp++);
 381        bp++; /* group */
 382        bp++; /* sync counter */
 383        vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
 384        bp++; /* spare2 */
 385        bp++; /* spare3 */
 386        bp++; /* spare4 */
 387
 388        vnode->cb_version               = ntohl(*bp++);
 389        vnode->cb_expiry                = ntohl(*bp++);
 390        vnode->cb_type                  = ntohl(*bp++);
 391
 392        if (volsync) {
 393                volsync->creation       = ntohl(*bp++);
 394                bp++; /* spare2 */
 395                bp++; /* spare3 */
 396                bp++; /* spare4 */
 397                bp++; /* spare5 */
 398                bp++; /* spare6 */
 399        }
 400
 401        /* success */
 402        ret = 0;
 403
 404 out_unwait:
 405        set_current_state(TASK_RUNNING);
 406        remove_wait_queue(&call->waitq, &myself);
 407        rxrpc_put_call(call);
 408 out_put_conn:
 409        afs_server_release_callslot(server, &callslot);
 410 out:
 411        _leave("");
 412        return ret;
 413
 414 abort:
 415        set_current_state(TASK_UNINTERRUPTIBLE);
 416        rxrpc_call_abort(call, ret);
 417        schedule();
 418        goto out_unwait;
 419} /* end afs_rxfs_fetch_file_status() */
 420
 421/*****************************************************************************/
 422/*
 423 * fetch the contents of a file or directory
 424 */
 425int afs_rxfs_fetch_file_data(struct afs_server *server,
 426                             struct afs_vnode *vnode,
 427                             struct afs_rxfs_fetch_descriptor *desc,
 428                             struct afs_volsync *volsync)
 429{
 430        struct afs_server_callslot callslot;
 431        struct rxrpc_call *call;
 432        struct kvec piov[1];
 433        size_t sent;
 434        int ret;
 435        __be32 *bp;
 436
 437        DECLARE_WAITQUEUE(myself, current);
 438
 439        _enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}",
 440               server,
 441               desc->fid.vid,
 442               desc->fid.vnode,
 443               desc->fid.unique,
 444               desc->size,
 445               desc->offset);
 446
 447        /* get hold of the fileserver connection */
 448        ret = afs_server_request_callslot(server, &callslot);
 449        if (ret < 0)
 450                goto out;
 451
 452        /* create a call through that connection */
 453        ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call);
 454        if (ret < 0) {
 455                printk("kAFS: Unable to create call: %d\n", ret);
 456                goto out_put_conn;
 457        }
 458        call->app_opcode = FSFETCHDATA;
 459
 460        /* we want to get event notifications from the call */
 461        add_wait_queue(&call->waitq, &myself);
 462
 463        /* marshall the parameters */
 464        bp = rxrpc_call_alloc_scratch(call, 24);
 465        bp[0] = htonl(FSFETCHDATA);
 466        bp[1] = htonl(desc->fid.vid);
 467        bp[2] = htonl(desc->fid.vnode);
 468        bp[3] = htonl(desc->fid.unique);
 469        bp[4] = htonl(desc->offset);
 470        bp[5] = htonl(desc->size);
 471
 472        piov[0].iov_len = 24;
 473        piov[0].iov_base = bp;
 474
 475        /* send the parameters to the server */
 476        ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
 477                                    0, &sent);
 478        if (ret < 0)
 479                goto abort;
 480
 481        /* wait for the data count to arrive */
 482        ret = rxrpc_call_read_data(call, bp, 4, RXRPC_CALL_READ_BLOCK);
 483        if (ret < 0)
 484                goto read_failed;
 485
 486        desc->actual = ntohl(bp[0]);
 487        if (desc->actual != desc->size) {
 488                ret = -EBADMSG;
 489                goto abort;
 490        }
 491
 492        /* call the app to read the actual data */
 493        rxrpc_call_reset_scratch(call);
 494
 495        ret = rxrpc_call_read_data(call, desc->buffer, desc->actual,
 496                                   RXRPC_CALL_READ_BLOCK);
 497        if (ret < 0)
 498                goto read_failed;
 499
 500        /* wait for the rest of the reply to completely arrive */
 501        rxrpc_call_reset_scratch(call);
 502        bp = rxrpc_call_alloc_scratch(call, 120);
 503
 504        ret = rxrpc_call_read_data(call, bp, 120,
 505                                   RXRPC_CALL_READ_BLOCK |
 506                                   RXRPC_CALL_READ_ALL);
 507        if (ret < 0)
 508                goto read_failed;
 509
 510        /* unmarshall the reply */
 511        vnode->status.if_version        = ntohl(*bp++);
 512        vnode->status.type              = ntohl(*bp++);
 513        vnode->status.nlink             = ntohl(*bp++);
 514        vnode->status.size              = ntohl(*bp++);
 515        vnode->status.version           = ntohl(*bp++);
 516        vnode->status.author            = ntohl(*bp++);
 517        vnode->status.owner             = ntohl(*bp++);
 518        vnode->status.caller_access     = ntohl(*bp++);
 519        vnode->status.anon_access       = ntohl(*bp++);
 520        vnode->status.mode              = ntohl(*bp++);
 521        vnode->status.parent.vid        = desc->fid.vid;
 522        vnode->status.parent.vnode      = ntohl(*bp++);
 523        vnode->status.parent.unique     = ntohl(*bp++);
 524        bp++; /* seg size */
 525        vnode->status.mtime_client      = ntohl(*bp++);
 526        vnode->status.mtime_server      = ntohl(*bp++);
 527        bp++; /* group */
 528        bp++; /* sync counter */
 529        vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
 530        bp++; /* spare2 */
 531        bp++; /* spare3 */
 532        bp++; /* spare4 */
 533
 534        vnode->cb_version               = ntohl(*bp++);
 535        vnode->cb_expiry                = ntohl(*bp++);
 536        vnode->cb_type                  = ntohl(*bp++);
 537
 538        if (volsync) {
 539                volsync->creation       = ntohl(*bp++);
 540                bp++; /* spare2 */
 541                bp++; /* spare3 */
 542                bp++; /* spare4 */
 543                bp++; /* spare5 */
 544                bp++; /* spare6 */
 545        }
 546
 547        /* success */
 548        ret = 0;
 549
 550 out_unwait:
 551        set_current_state(TASK_RUNNING);
 552        remove_wait_queue(&call->waitq,&myself);
 553        rxrpc_put_call(call);
 554 out_put_conn:
 555        afs_server_release_callslot(server, &callslot);
 556 out:
 557        _leave(" = %d", ret);
 558        return ret;
 559
 560 read_failed:
 561        if (ret == -ECONNABORTED) {
 562                ret = call->app_errno;
 563                goto out_unwait;
 564        }
 565
 566 abort:
 567        set_current_state(TASK_UNINTERRUPTIBLE);
 568        rxrpc_call_abort(call, ret);
 569        schedule();
 570        goto out_unwait;
 571
 572} /* end afs_rxfs_fetch_file_data() */
 573
 574/*****************************************************************************/
 575/*
 576 * ask the AFS fileserver to discard a callback request on a file
 577 */
 578int afs_rxfs_give_up_callback(struct afs_server *server,
 579                              struct afs_vnode *vnode)
 580{
 581        struct afs_server_callslot callslot;
 582        struct rxrpc_call *call;
 583        struct kvec piov[1];
 584        size_t sent;
 585        int ret;
 586        __be32 *bp;
 587
 588        DECLARE_WAITQUEUE(myself, current);
 589
 590        _enter("%p,{%u,%u,%u}",
 591               server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
 592
 593        /* get hold of the fileserver connection */
 594        ret = afs_server_request_callslot(server, &callslot);
 595        if (ret < 0)
 596                goto out;
 597
 598        /* create a call through that connection */
 599        ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call);
 600        if (ret < 0) {
 601                printk("kAFS: Unable to create call: %d\n", ret);
 602                goto out_put_conn;
 603        }
 604        call->app_opcode = FSGIVEUPCALLBACKS;
 605
 606        /* we want to get event notifications from the call */
 607        add_wait_queue(&call->waitq, &myself);
 608
 609        /* marshall the parameters */
 610        bp = rxrpc_call_alloc_scratch(call, (1 + 4 + 4) * 4);
 611
 612        piov[0].iov_len = (1 + 4 + 4) * 4;
 613        piov[0].iov_base = bp;
 614
 615        *bp++ = htonl(FSGIVEUPCALLBACKS);
 616        *bp++ = htonl(1);
 617        *bp++ = htonl(vnode->fid.vid);
 618        *bp++ = htonl(vnode->fid.vnode);
 619        *bp++ = htonl(vnode->fid.unique);
 620        *bp++ = htonl(1);
 621        *bp++ = htonl(vnode->cb_version);
 622        *bp++ = htonl(vnode->cb_expiry);
 623        *bp++ = htonl(vnode->cb_type);
 624
 625        /* send the parameters to the server */
 626        ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
 627                                    0, &sent);
 628        if (ret < 0)
 629                goto abort;
 630
 631        /* wait for the reply to completely arrive */
 632        for (;;) {
 633                set_current_state(TASK_INTERRUPTIBLE);
 634                if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
 635                    signal_pending(current))
 636                        break;
 637                schedule();
 638        }
 639        set_current_state(TASK_RUNNING);
 640
 641        ret = -EINTR;
 642        if (signal_pending(current))
 643                goto abort;
 644
 645        switch (call->app_call_state) {
 646        case RXRPC_CSTATE_ERROR:
 647                ret = call->app_errno;
 648                goto out_unwait;
 649
 650        case RXRPC_CSTATE_CLNT_GOT_REPLY:
 651                ret = 0;
 652                goto out_unwait;
 653
 654        default:
 655                BUG();
 656        }
 657
 658 out_unwait:
 659        set_current_state(TASK_RUNNING);
 660        remove_wait_queue(&call->waitq, &myself);
 661        rxrpc_put_call(call);
 662 out_put_conn:
 663        afs_server_release_callslot(server, &callslot);
 664 out:
 665        _leave("");
 666        return ret;
 667
 668 abort:
 669        set_current_state(TASK_UNINTERRUPTIBLE);
 670        rxrpc_call_abort(call, ret);
 671        schedule();
 672        goto out_unwait;
 673} /* end afs_rxfs_give_up_callback() */
 674
 675/*****************************************************************************/
 676/*
 677 * look a filename up in a directory
 678 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
 679 */
 680#if 0
 681int afs_rxfs_lookup(struct afs_server *server,
 682                    struct afs_vnode *dir,
 683                    const char *filename,
 684                    struct afs_vnode *vnode,
 685                    struct afs_volsync *volsync)
 686{
 687        struct rxrpc_connection *conn;
 688        struct rxrpc_call *call;
 689        struct kvec piov[3];
 690        size_t sent;
 691        int ret;
 692        u32 *bp, zero;
 693
 694        DECLARE_WAITQUEUE(myself, current);
 695
 696        kenter("%p,{%u,%u,%u},%s",
 697               server, fid->vid, fid->vnode, fid->unique, filename);
 698
 699        /* get hold of the fileserver connection */
 700        ret = afs_server_get_fsconn(server, &conn);
 701        if (ret < 0)
 702                goto out;
 703
 704        /* create a call through that connection */
 705        ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
 706        if (ret < 0) {
 707                printk("kAFS: Unable to create call: %d\n", ret);
 708                goto out_put_conn;
 709        }
 710        call->app_opcode = FSLOOKUP;
 711
 712        /* we want to get event notifications from the call */
 713        add_wait_queue(&call->waitq,&myself);
 714
 715        /* marshall the parameters */
 716        bp = rxrpc_call_alloc_scratch(call, 20);
 717
 718        zero = 0;
 719
 720        piov[0].iov_len = 20;
 721        piov[0].iov_base = bp;
 722        piov[1].iov_len = strlen(filename);
 723        piov[1].iov_base = (char *) filename;
 724        piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
 725        piov[2].iov_base = &zero;
 726
 727        *bp++ = htonl(FSLOOKUP);
 728        *bp++ = htonl(dirfid->vid);
 729        *bp++ = htonl(dirfid->vnode);
 730        *bp++ = htonl(dirfid->unique);
 731        *bp++ = htonl(piov[1].iov_len);
 732
 733        /* send the parameters to the server */
 734        ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
 735                                    0, &sent);
 736        if (ret < 0)
 737                goto abort;
 738
 739        /* wait for the reply to completely arrive */
 740        bp = rxrpc_call_alloc_scratch(call, 220);
 741
 742        ret = rxrpc_call_read_data(call, bp, 220,
 743                                   RXRPC_CALL_READ_BLOCK |
 744                                   RXRPC_CALL_READ_ALL);
 745        if (ret < 0) {
 746                if (ret == -ECONNABORTED) {
 747                        ret = call->app_errno;
 748                        goto out_unwait;
 749                }
 750                goto abort;
 751        }
 752
 753        /* unmarshall the reply */
 754        fid->vid                = ntohl(*bp++);
 755        fid->vnode              = ntohl(*bp++);
 756        fid->unique             = ntohl(*bp++);
 757
 758        vnode->status.if_version        = ntohl(*bp++);
 759        vnode->status.type              = ntohl(*bp++);
 760        vnode->status.nlink             = ntohl(*bp++);
 761        vnode->status.size              = ntohl(*bp++);
 762        vnode->status.version           = ntohl(*bp++);
 763        vnode->status.author            = ntohl(*bp++);
 764        vnode->status.owner             = ntohl(*bp++);
 765        vnode->status.caller_access     = ntohl(*bp++);
 766        vnode->status.anon_access       = ntohl(*bp++);
 767        vnode->status.mode              = ntohl(*bp++);
 768        vnode->status.parent.vid        = dirfid->vid;
 769        vnode->status.parent.vnode      = ntohl(*bp++);
 770        vnode->status.parent.unique     = ntohl(*bp++);
 771        bp++; /* seg size */
 772        vnode->status.mtime_client      = ntohl(*bp++);
 773        vnode->status.mtime_server      = ntohl(*bp++);
 774        bp++; /* group */
 775        bp++; /* sync counter */
 776        vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
 777        bp++; /* spare2 */
 778        bp++; /* spare3 */
 779        bp++; /* spare4 */
 780
 781        dir->status.if_version          = ntohl(*bp++);
 782        dir->status.type                = ntohl(*bp++);
 783        dir->status.nlink               = ntohl(*bp++);
 784        dir->status.size                = ntohl(*bp++);
 785        dir->status.version             = ntohl(*bp++);
 786        dir->status.author              = ntohl(*bp++);
 787        dir->status.owner               = ntohl(*bp++);
 788        dir->status.caller_access       = ntohl(*bp++);
 789        dir->status.anon_access         = ntohl(*bp++);
 790        dir->status.mode                = ntohl(*bp++);
 791        dir->status.parent.vid          = dirfid->vid;
 792        dir->status.parent.vnode        = ntohl(*bp++);
 793        dir->status.parent.unique       = ntohl(*bp++);
 794        bp++; /* seg size */
 795        dir->status.mtime_client        = ntohl(*bp++);
 796        dir->status.mtime_server        = ntohl(*bp++);
 797        bp++; /* group */
 798        bp++; /* sync counter */
 799        dir->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
 800        bp++; /* spare2 */
 801        bp++; /* spare3 */
 802        bp++; /* spare4 */
 803
 804        callback->fid           = *fid;
 805        callback->version       = ntohl(*bp++);
 806        callback->expiry        = ntohl(*bp++);
 807        callback->type          = ntohl(*bp++);
 808
 809        if (volsync) {
 810                volsync->creation       = ntohl(*bp++);
 811                bp++; /* spare2 */
 812                bp++; /* spare3 */
 813                bp++; /* spare4 */
 814                bp++; /* spare5 */
 815                bp++; /* spare6 */
 816        }
 817
 818        /* success */
 819        ret = 0;
 820
 821 out_unwait:
 822        set_current_state(TASK_RUNNING);
 823        remove_wait_queue(&call->waitq, &myself);
 824        rxrpc_put_call(call);
 825 out_put_conn:
 826        afs_server_release_fsconn(server, conn);
 827 out:
 828        kleave("");
 829        return ret;
 830
 831 abort:
 832        set_current_state(TASK_UNINTERRUPTIBLE);
 833        rxrpc_call_abort(call, ret);
 834        schedule();
 835        goto out_unwait;
 836} /* end afs_rxfs_lookup() */
 837#endif
 838
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.