root/fs/nfs/proc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfs_rpc_alloc
  2. nfs_rpc_free
  3. xdr_encode_fhandle
  4. xdr_decode_fhandle
  5. xdr_encode_string
  6. xdr_decode_string
  7. xdr_encode_data
  8. xdr_decode_data
  9. xdr_decode_fattr
  10. xdr_encode_sattr
  11. xdr_decode_entry
  12. xdr_decode_fsinfo
  13. nfs_proc_getattr
  14. nfs_proc_setattr
  15. nfs_proc_lookup
  16. nfs_proc_readlink
  17. nfs_proc_read
  18. nfs_proc_write
  19. nfs_proc_create
  20. nfs_proc_remove
  21. nfs_proc_rename
  22. nfs_proc_link
  23. nfs_proc_symlink
  24. nfs_proc_mkdir
  25. nfs_proc_rmdir
  26. nfs_proc_readdir
  27. nfs_proc_statfs
  28. nfs_rpc_header
  29. nfs_rpc_verify
  30. nfs_stat_to_errno

   1 /*
   2  *  linux/fs/nfs/proc.c
   3  *
   4  *  Copyright (C) 1992  Rick Sladkey
   5  *
   6  *  OS-independent nfs remote procedure call functions
   7  */
   8 
   9 /*
  10  * Defining NFS_PROC_DEBUG causes a lookup of a file named
  11  * "xyzzy" to toggle debugging.  Just cd to an NFS-mounted
  12  * filesystem and type 'ls xyzzy' to turn on debugging.
  13  */
  14 
  15 #if 0
  16 #define NFS_PROC_DEBUG
  17 #endif
  18 
  19 #include <linux/config.h>
  20 #include <linux/param.h>
  21 #include <linux/sched.h>
  22 #include <linux/mm.h>
  23 #include <linux/nfs_fs.h>
  24 #include <linux/utsname.h>
  25 #include <linux/errno.h>
  26 #include <linux/string.h>
  27 #include <linux/in.h>
  28 
  29 #ifdef NFS_PROC_DEBUG
  30 
  31 static int proc_debug = 0;
  32 #define PRINTK(format, args...) \
  33         do {                                            \
  34                 if (proc_debug)                         \
  35                         printk(format , ## args);       \
  36         } while (0)
  37 
  38 #else /* !NFS_PROC_DEBUG */
  39 
  40 #define PRINTK(format, args...) do ; while (0)
  41 
  42 #endif /* !NFS_PROC_DEBUG */
  43 
  44 static int *nfs_rpc_header(int *p, int procedure);
  45 static int *nfs_rpc_verify(int *p);
  46 static int nfs_stat_to_errno(int stat);
  47 
  48 /*
  49  * Our memory allocation and release functions.
  50  */
  51 
  52 static inline int *nfs_rpc_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54         return (int *) __get_free_page(GFP_KERNEL);
  55 }
  56 
  57 static inline void nfs_rpc_free(int *p)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59         free_page((long) p);
  60 }
  61 
  62 /*
  63  * Here are a bunch of xdr encode/decode functions that convert
  64  * between machine dependent and xdr data formats.
  65  */
  66 
  67 static inline int *xdr_encode_fhandle(int *p, struct nfs_fh *fhandle)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         *((struct nfs_fh *) p) = *fhandle;
  70         p += (sizeof (*fhandle) + 3) >> 2;
  71         return p;
  72 }
  73 
  74 static inline int *xdr_decode_fhandle(int *p, struct nfs_fh *fhandle)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         *fhandle = *((struct nfs_fh *) p);
  77         p += (sizeof (*fhandle) + 3) >> 2;
  78         return p;
  79 }
  80 
  81 static inline int *xdr_encode_string(int *p, const char *string)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83         int len, quadlen;
  84         
  85         len = strlen(string);
  86         quadlen = (len + 3) >> 2;
  87         *p++ = htonl(len);
  88         memcpy((char *) p, string, len);
  89         memset(((char *) p) + len, '\0', (quadlen << 2) - len);
  90         p += quadlen;
  91         return p;
  92 }
  93 
  94 static inline int *xdr_decode_string(int *p, char *string, int maxlen)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         unsigned int len;
  97 
  98         len = ntohl(*p++);
  99         if (len > maxlen)
 100                 return NULL;
 101         memcpy(string, (char *) p, len);
 102         string[len] = '\0';
 103         p += (len + 3) >> 2;
 104         return p;
 105 }
 106 
 107 static inline int *xdr_encode_data(int *p, char *data, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         int quadlen;
 110         
 111         quadlen = (len + 3) >> 2;
 112         *p++ = htonl(len);
 113         memcpy((char *) p, data, len);
 114         memset(((char *) p) + len, '\0', (quadlen << 2) - len);
 115         p += quadlen;
 116         return p;
 117 }
 118 
 119 static inline int *xdr_decode_data(int *p, char *data, int *lenp, int maxlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121         unsigned int len;
 122 
 123         len = *lenp = ntohl(*p++);
 124         if (len > maxlen)
 125                 return NULL;
 126         memcpy(data, (char *) p, len);
 127         p += (len + 3) >> 2;
 128         return p;
 129 }
 130 
 131 static int *xdr_decode_fattr(int *p, struct nfs_fattr *fattr)
     /* [previous][next][first][last][top][bottom][index][help] */
 132 {
 133         fattr->type = (enum nfs_ftype) ntohl(*p++);
 134         fattr->mode = ntohl(*p++);
 135         fattr->nlink = ntohl(*p++);
 136         fattr->uid = ntohl(*p++);
 137         fattr->gid = ntohl(*p++);
 138         fattr->size = ntohl(*p++);
 139         fattr->blocksize = ntohl(*p++);
 140         fattr->rdev = ntohl(*p++);
 141         fattr->blocks = ntohl(*p++);
 142         fattr->fsid = ntohl(*p++);
 143         fattr->fileid = ntohl(*p++);
 144         fattr->atime.seconds = ntohl(*p++);
 145         fattr->atime.useconds = ntohl(*p++);
 146         fattr->mtime.seconds = ntohl(*p++);
 147         fattr->mtime.useconds = ntohl(*p++);
 148         fattr->ctime.seconds = ntohl(*p++);
 149         fattr->ctime.useconds = ntohl(*p++);
 150         return p;
 151 }
 152 
 153 static int *xdr_encode_sattr(int *p, struct nfs_sattr *sattr)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155         *p++ = htonl(sattr->mode);
 156         *p++ = htonl(sattr->uid);
 157         *p++ = htonl(sattr->gid);
 158         *p++ = htonl(sattr->size);
 159         *p++ = htonl(sattr->atime.seconds);
 160         *p++ = htonl(sattr->atime.useconds);
 161         *p++ = htonl(sattr->mtime.seconds);
 162         *p++ = htonl(sattr->mtime.useconds);
 163         return p;
 164 }
 165 
 166 static int *xdr_decode_entry(int *p, struct nfs_entry *entry)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168         entry->fileid = ntohl(*p++);
 169         if (!(p = xdr_decode_string(p, entry->name, NFS_MAXNAMLEN)))
 170                 return NULL;
 171         entry->cookie = ntohl(*p++);
 172         entry->eof = 0;
 173         return p;
 174 }
 175 
 176 static int *xdr_decode_fsinfo(int *p, struct nfs_fsinfo *res)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         res->tsize = ntohl(*p++);
 179         res->bsize = ntohl(*p++);
 180         res->blocks = ntohl(*p++);
 181         res->bfree = ntohl(*p++);
 182         res->bavail = ntohl(*p++);
 183         return p;
 184 }
 185 
 186 /*
 187  * One function for each procedure in the NFS protocol.
 188  */
 189 
 190 int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 191                      struct nfs_fattr *fattr)
 192 {
 193         int *p, *p0;
 194         int status;
 195 
 196         PRINTK("NFS call  getattr\n");
 197         if (!(p0 = nfs_rpc_alloc()))
 198                 return -EIO;
 199         p = nfs_rpc_header(p0, NFSPROC_GETATTR);
 200         p = xdr_encode_fhandle(p, fhandle);
 201         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 202                 nfs_rpc_free(p0);
 203                 return status;
 204         }
 205         if (!(p = nfs_rpc_verify(p0)))
 206                 status = NFSERR_IO;
 207         else if ((status = ntohl(*p++)) == NFS_OK) {
 208                 p = xdr_decode_fattr(p, fattr);
 209                 PRINTK("NFS reply getattr\n");
 210         }
 211         else
 212                 PRINTK("NFS reply getattr failed = %d\n", status);
 213         nfs_rpc_free(p0);
 214         return -nfs_stat_to_errno(status);
 215 }
 216 
 217 int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 218                      struct nfs_sattr *sattr, struct nfs_fattr *fattr)
 219 {
 220         int *p, *p0;
 221         int status;
 222 
 223         PRINTK("NFS call  setattr\n");
 224         if (!(p0 = nfs_rpc_alloc()))
 225                 return -EIO;
 226         p = nfs_rpc_header(p0, NFSPROC_SETATTR);
 227         p = xdr_encode_fhandle(p, fhandle);
 228         p = xdr_encode_sattr(p, sattr);
 229         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 230                 nfs_rpc_free(p0);
 231                 return status;
 232         }
 233         if (!(p = nfs_rpc_verify(p0)))
 234                 status = NFSERR_IO;
 235         else if ((status = ntohl(*p++)) == NFS_OK) {
 236                 p = xdr_decode_fattr(p, fattr);
 237                 PRINTK("NFS reply setattr\n");
 238         }
 239         else
 240                 PRINTK("NFS reply setattr failed = %d\n", status);
 241         nfs_rpc_free(p0);
 242         return -nfs_stat_to_errno(status);
 243 }
 244 
 245 int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *name,
     /* [previous][next][first][last][top][bottom][index][help] */
 246                     struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 247 {
 248         int *p, *p0;
 249         int status;
 250 
 251         PRINTK("NFS call  lookup %s\n", name);
 252 #ifdef NFS_PROC_DEBUG
 253         if (!strcmp(name, "xyzzy"))
 254                 proc_debug = 1 - proc_debug;
 255 #endif
 256         if (!(p0 = nfs_rpc_alloc()))
 257                 return -EIO;
 258         p = nfs_rpc_header(p0, NFSPROC_LOOKUP);
 259         p = xdr_encode_fhandle(p, dir);
 260         p = xdr_encode_string(p, name);
 261         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 262                 nfs_rpc_free(p0);
 263                 return status;
 264         }
 265         if (!(p = nfs_rpc_verify(p0)))
 266                 status = NFSERR_IO;
 267         else if ((status = ntohl(*p++)) == NFS_OK) {
 268                 p = xdr_decode_fhandle(p, fhandle);
 269                 p = xdr_decode_fattr(p, fattr);
 270                 PRINTK("NFS reply lookup\n");
 271         }
 272         else
 273                 PRINTK("NFS reply lookup failed = %d\n", status);
 274         nfs_rpc_free(p0);
 275         return -nfs_stat_to_errno(status);
 276 }
 277 
 278 int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 279                       char *res)
 280 {
 281         int *p, *p0;
 282         int status;
 283 
 284         PRINTK("NFS call  readlink\n");
 285         if (!(p0 = nfs_rpc_alloc()))
 286                 return -EIO;
 287         p = nfs_rpc_header(p0, NFSPROC_READLINK);
 288         p = xdr_encode_fhandle(p, fhandle);
 289         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 290                 nfs_rpc_free(p0);
 291                 return status;
 292         }
 293         if (!(p = nfs_rpc_verify(p0)))
 294                 status = NFSERR_IO;
 295         else if ((status = ntohl(*p++)) == NFS_OK) {
 296                 if (!(p = xdr_decode_string(p, res, NFS_MAXPATHLEN))) {
 297                         printk("nfs_proc_readlink: giant pathname\n");
 298                         status = NFSERR_IO;
 299                 }
 300                 else
 301                         PRINTK("NFS reply readlink %s\n", res);
 302         }
 303         else
 304                 PRINTK("NFS reply readlink failed = %d\n", status);
 305         nfs_rpc_free(p0);
 306         return -nfs_stat_to_errno(status);
 307 }
 308 
 309 int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 310                   int offset, int count, char *data, struct nfs_fattr *fattr)
 311 {
 312         int *p, *p0;
 313         int status;
 314         int len = 0; /* = 0 is for gcc */
 315 
 316         PRINTK("NFS call  read %d @ %d\n", count, offset);
 317         if (!(p0 = nfs_rpc_alloc()))
 318                 return -EIO;
 319         p = nfs_rpc_header(p0, NFSPROC_READ);
 320         p = xdr_encode_fhandle(p, fhandle);
 321         *p++ = htonl(offset);
 322         *p++ = htonl(count);
 323         *p++ = htonl(count); /* traditional, could be any value */
 324         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 325                 nfs_rpc_free(p0);
 326                 return status;
 327         }
 328         if (!(p = nfs_rpc_verify(p0)))
 329                 status = NFSERR_IO;
 330         else if ((status = ntohl(*p++)) == NFS_OK) {
 331                 p = xdr_decode_fattr(p, fattr);
 332                 if (!(p = xdr_decode_data(p, data, &len, count))) {
 333                         printk("nfs_proc_read: giant data size\n"); 
 334                         status = NFSERR_IO;
 335                 }
 336                 else
 337                         PRINTK("NFS reply read %d\n", len);
 338         }
 339         else
 340                 PRINTK("NFS reply read failed = %d\n", status);
 341         nfs_rpc_free(p0);
 342         return (status == NFS_OK) ? len : -nfs_stat_to_errno(status);
 343 }
 344 
 345 int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 346                    int offset, int count, char *data, struct nfs_fattr *fattr)
 347 {
 348         int *p, *p0;
 349         int status;
 350 
 351         PRINTK("NFS call  write %d @ %d\n", count, offset);
 352         if (!(p0 = nfs_rpc_alloc()))
 353                 return -EIO;
 354         p = nfs_rpc_header(p0, NFSPROC_WRITE);
 355         p = xdr_encode_fhandle(p, fhandle);
 356         *p++ = htonl(offset); /* traditional, could be any value */
 357         *p++ = htonl(offset);
 358         *p++ = htonl(count); /* traditional, could be any value */
 359         p = xdr_encode_data(p, data, count);
 360         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 361                 nfs_rpc_free(p0);
 362                 return status;
 363         }
 364         if (!(p = nfs_rpc_verify(p0)))
 365                 status = NFSERR_IO;
 366         else if ((status = ntohl(*p++)) == NFS_OK) {
 367                 p = xdr_decode_fattr(p, fattr);
 368                 PRINTK("NFS reply write\n");
 369         }
 370         else
 371                 PRINTK("NFS reply write failed = %d\n", status);
 372         nfs_rpc_free(p0);
 373         return -nfs_stat_to_errno(status);
 374 }
 375 
 376 int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 377                     const char *name, struct nfs_sattr *sattr,
 378                     struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 379 {
 380         int *p, *p0;
 381         int status;
 382 
 383         PRINTK("NFS call  create %s\n", name);
 384         if (!(p0 = nfs_rpc_alloc()))
 385                 return -EIO;
 386         p = nfs_rpc_header(p0, NFSPROC_CREATE);
 387         p = xdr_encode_fhandle(p, dir);
 388         p = xdr_encode_string(p, name);
 389         p = xdr_encode_sattr(p, sattr);
 390         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 391                 nfs_rpc_free(p0);
 392                 return status;
 393         }
 394         if (!(p = nfs_rpc_verify(p0)))
 395                 status = NFSERR_IO;
 396         else if ((status = ntohl(*p++)) == NFS_OK) {
 397                 p = xdr_decode_fhandle(p, fhandle);
 398                 p = xdr_decode_fattr(p, fattr);
 399                 PRINTK("NFS reply create\n");
 400         }
 401         else
 402                 PRINTK("NFS reply create failed = %d\n", status);
 403         nfs_rpc_free(p0);
 404         return -nfs_stat_to_errno(status);
 405 }
 406 
 407 int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 408 {
 409         int *p, *p0;
 410         int status;
 411 
 412         PRINTK("NFS call  remove %s\n", name);
 413         if (!(p0 = nfs_rpc_alloc()))
 414                 return -EIO;
 415         p = nfs_rpc_header(p0, NFSPROC_REMOVE);
 416         p = xdr_encode_fhandle(p, dir);
 417         p = xdr_encode_string(p, name);
 418         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 419                 nfs_rpc_free(p0);
 420                 return status;
 421         }
 422         if (!(p = nfs_rpc_verify(p0)))
 423                 status = NFSERR_IO;
 424         else if ((status = ntohl(*p++)) == NFS_OK) {
 425                 PRINTK("NFS reply remove\n");
 426         }
 427         else
 428                 PRINTK("NFS reply remove failed = %d\n", status);
 429         nfs_rpc_free(p0);
 430         return -nfs_stat_to_errno(status);
 431 }
 432 
 433 int nfs_proc_rename(struct nfs_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 434                     struct nfs_fh *old_dir, const char *old_name,
 435                     struct nfs_fh *new_dir, const char *new_name)
 436 {
 437         int *p, *p0;
 438         int status;
 439 
 440         PRINTK("NFS call  rename %s -> %s\n", old_name, new_name);
 441         if (!(p0 = nfs_rpc_alloc()))
 442                 return -EIO;
 443         p = nfs_rpc_header(p0, NFSPROC_RENAME);
 444         p = xdr_encode_fhandle(p, old_dir);
 445         p = xdr_encode_string(p, old_name);
 446         p = xdr_encode_fhandle(p, new_dir);
 447         p = xdr_encode_string(p, new_name);
 448         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 449                 nfs_rpc_free(p0);
 450                 return status;
 451         }
 452         if (!(p = nfs_rpc_verify(p0)))
 453                 status = NFSERR_IO;
 454         else if ((status = ntohl(*p++)) == NFS_OK) {
 455                 PRINTK("NFS reply rename\n");
 456         }
 457         else
 458                 PRINTK("NFS reply rename failed = %d\n", status);
 459         nfs_rpc_free(p0);
 460         return -nfs_stat_to_errno(status);
 461 }
 462 
 463 int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 464                   struct nfs_fh *dir, const char *name)
 465 {
 466         int *p, *p0;
 467         int status;
 468 
 469         PRINTK("NFS call  link %s\n", name);
 470         if (!(p0 = nfs_rpc_alloc()))
 471                 return -EIO;
 472         p = nfs_rpc_header(p0, NFSPROC_LINK);
 473         p = xdr_encode_fhandle(p, fhandle);
 474         p = xdr_encode_fhandle(p, dir);
 475         p = xdr_encode_string(p, name);
 476         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 477                 nfs_rpc_free(p0);
 478                 return status;
 479         }
 480         if (!(p = nfs_rpc_verify(p0)))
 481                 status = NFSERR_IO;
 482         else if ((status = ntohl(*p++)) == NFS_OK) {
 483                 PRINTK("NFS reply link\n");
 484         }
 485         else
 486                 PRINTK("NFS reply link failed = %d\n", status);
 487         nfs_rpc_free(p0);
 488         return -nfs_stat_to_errno(status);
 489 }
 490 
 491 int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 492                      const char *name, const char *path, struct nfs_sattr *sattr)
 493 {
 494         int *p, *p0;
 495         int status;
 496 
 497         PRINTK("NFS call  symlink %s -> %s\n", name, path);
 498         if (!(p0 = nfs_rpc_alloc()))
 499                 return -EIO;
 500         p = nfs_rpc_header(p0, NFSPROC_SYMLINK);
 501         p = xdr_encode_fhandle(p, dir);
 502         p = xdr_encode_string(p, name);
 503         p = xdr_encode_string(p, path);
 504         p = xdr_encode_sattr(p, sattr);
 505         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 506                 nfs_rpc_free(p0);
 507                 return status;
 508         }
 509         if (!(p = nfs_rpc_verify(p0)))
 510                 status = NFSERR_IO;
 511         else if ((status = ntohl(*p++)) == NFS_OK) {
 512                 PRINTK("NFS reply symlink\n");
 513         }
 514         else
 515                 PRINTK("NFS reply symlink failed = %d\n", status);
 516         nfs_rpc_free(p0);
 517         return -nfs_stat_to_errno(status);
 518 }
 519 
 520 int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 521                    const char *name, struct nfs_sattr *sattr,
 522                    struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 523 {
 524         int *p, *p0;
 525         int status;
 526 
 527         PRINTK("NFS call  mkdir %s\n", name);
 528         if (!(p0 = nfs_rpc_alloc()))
 529                 return -EIO;
 530         p = nfs_rpc_header(p0, NFSPROC_MKDIR);
 531         p = xdr_encode_fhandle(p, dir);
 532         p = xdr_encode_string(p, name);
 533         p = xdr_encode_sattr(p, sattr);
 534         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 535                 nfs_rpc_free(p0);
 536                 return status;
 537         }
 538         if (!(p = nfs_rpc_verify(p0)))
 539                 status = NFSERR_IO;
 540         else if ((status = ntohl(*p++)) == NFS_OK) {
 541                 p = xdr_decode_fhandle(p, fhandle);
 542                 p = xdr_decode_fattr(p, fattr);
 543                 PRINTK("NFS reply mkdir\n");
 544         }
 545         else
 546                 PRINTK("NFS reply mkdir failed = %d\n", status);
 547         nfs_rpc_free(p0);
 548         return -nfs_stat_to_errno(status);
 549 }
 550 
 551 int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 552 {
 553         int *p, *p0;
 554         int status;
 555 
 556         PRINTK("NFS call  rmdir %s\n", name);
 557         if (!(p0 = nfs_rpc_alloc()))
 558                 return -EIO;
 559         p = nfs_rpc_header(p0, NFSPROC_RMDIR);
 560         p = xdr_encode_fhandle(p, dir);
 561         p = xdr_encode_string(p, name);
 562         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 563                 nfs_rpc_free(p0);
 564                 return status;
 565         }
 566         if (!(p = nfs_rpc_verify(p0)))
 567                 status = NFSERR_IO;
 568         else if ((status = ntohl(*p++)) == NFS_OK) {
 569                 PRINTK("NFS reply rmdir\n");
 570         }
 571         else
 572                 PRINTK("NFS reply rmdir failed = %d\n", status);
 573         nfs_rpc_free(p0);
 574         return -nfs_stat_to_errno(status);
 575 }
 576 
 577 int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 578                      int cookie, int count, struct nfs_entry *entry)
 579 {
 580         int *p, *p0;
 581         int status;
 582         int i = 0; /* = 0 is for gcc */
 583         int size;
 584         int eof;
 585 
 586         PRINTK("NFS call  readdir %d @ %d\n", count, cookie);
 587         size = server->rsize;
 588         if (!(p0 = nfs_rpc_alloc()))
 589                 return -EIO;
 590         p = nfs_rpc_header(p0, NFSPROC_READDIR);
 591         p = xdr_encode_fhandle(p, fhandle);
 592         *p++ = htonl(cookie);
 593         *p++ = htonl(size);
 594         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 595                 nfs_rpc_free(p0);
 596                 return status;
 597         }
 598         if (!(p = nfs_rpc_verify(p0)))
 599                 status = NFSERR_IO;
 600         else if ((status = ntohl(*p++)) == NFS_OK) {
 601                 for (i = 0; i < count && *p++; i++) {
 602                         if (!(p = xdr_decode_entry(p, entry++)))
 603                                 break;
 604                 }
 605                 if (!p) {
 606                         printk("nfs_proc_readdir: giant filename\n");
 607                         status = NFSERR_IO;
 608                 }
 609                 else {
 610                         eof = (i == count && !*p++ && *p++)
 611                               || (i < count && *p++);
 612                         if (eof && i)
 613                                 entry[-1].eof = 1;
 614                         PRINTK("NFS reply readdir %d %s\n", i,
 615                                eof ? "eof" : "");
 616                 }
 617         }
 618         else
 619                 PRINTK("NFS reply readdir failed = %d\n", status);
 620         nfs_rpc_free(p0);
 621         return (status == NFS_OK) ? i : -nfs_stat_to_errno(status);
 622 }
 623 
 624 int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 625                     struct nfs_fsinfo *res)
 626 {
 627         int *p, *p0;
 628         int status;
 629 
 630         PRINTK("NFS call  statfs\n");
 631         if (!(p0 = nfs_rpc_alloc()))
 632                 return -EIO;
 633         p = nfs_rpc_header(p0, NFSPROC_STATFS);
 634         p = xdr_encode_fhandle(p, fhandle);
 635         if ((status = nfs_rpc_call(server, p0, p)) < 0) {
 636                 nfs_rpc_free(p0);
 637                 return status;
 638         }
 639         if (!(p = nfs_rpc_verify(p0)))
 640                 status = NFSERR_IO;
 641         else if ((status = ntohl(*p++)) == NFS_OK) {
 642                 p = xdr_decode_fsinfo(p, res);
 643                 PRINTK("NFS reply statfs\n");
 644         }
 645         else
 646                 PRINTK("NFS reply statfs failed = %d\n", status);
 647         nfs_rpc_free(p0);
 648         return -nfs_stat_to_errno(status);
 649 }
 650 
 651 /*
 652  * Here are a few RPC-assist functions.
 653  */
 654 
 655 static int *nfs_rpc_header(int *p, int procedure)
     /* [previous][next][first][last][top][bottom][index][help] */
 656 {
 657         int *p1, *p2;
 658         int i;
 659         static int xid = 0;
 660         unsigned char *sys = (unsigned char *) system_utsname.nodename;
 661 
 662         if (xid == 0) {
 663                 xid = CURRENT_TIME;
 664                 xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
 665         }
 666         *p++ = htonl(++xid);
 667         *p++ = htonl(RPC_CALL);
 668         *p++ = htonl(RPC_VERSION);
 669         *p++ = htonl(NFS_PROGRAM);
 670         *p++ = htonl(NFS_VERSION);
 671         *p++ = htonl(procedure);
 672         *p++ = htonl(RPC_AUTH_UNIX);
 673         p1 = p++;
 674         *p++ = htonl(CURRENT_TIME); /* traditional, could be anything */
 675         p = xdr_encode_string(p, (char *) sys);
 676         *p++ = htonl(current->euid);
 677         *p++ = htonl(current->egid);
 678         p2 = p++;
 679         for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++)
 680                 *p++ = htonl(current->groups[i]);
 681         *p2 = htonl(i);
 682         *p1 = htonl((p - (p1 + 1)) << 2);
 683         *p++ = htonl(RPC_AUTH_NULL);
 684         *p++ = htonl(0);
 685         return p;
 686 }
 687 
 688 static int *nfs_rpc_verify(int *p)
     /* [previous][next][first][last][top][bottom][index][help] */
 689 {
 690         unsigned int n;
 691 
 692         p++;
 693         if ((n = ntohl(*p++)) != RPC_REPLY) {
 694                 printk("nfs_rpc_verify: not an RPC reply: %d\n", n);
 695                 return NULL;
 696         }
 697         if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
 698                 printk("nfs_rpc_verify: RPC call rejected: %d\n", n);
 699                 return NULL;
 700         }
 701         switch (n = ntohl(*p++)) {
 702         case RPC_AUTH_NULL: case RPC_AUTH_UNIX: case RPC_AUTH_SHORT:
 703                 break;
 704         default:
 705                 printk("nfs_rpc_verify: bad RPC authentication type: %d\n", n);
 706                 return NULL;
 707         }
 708         if ((n = ntohl(*p++)) > 400) {
 709                 printk("nfs_rpc_verify: giant auth size\n");
 710                 return NULL;
 711         }
 712         p += (n + 3) >> 2;
 713         if ((n = ntohl(*p++)) != RPC_SUCCESS) {
 714                 printk("nfs_rpc_verify: RPC call failed: %d\n", n);
 715                 return NULL;
 716         }
 717         return p;
 718 }
 719         
 720 /*
 721  * We need to translate between nfs status return values and
 722  * the local errno values which may not be the same.
 723  */
 724 
 725 #ifndef EDQUOT
 726 #define EDQUOT  ENOSPC
 727 #endif
 728 
 729 static struct {
 730         int stat;
 731         int errno;
 732 } nfs_errtbl[] = {
 733         { NFS_OK,               0               },
 734         { NFSERR_PERM,          EPERM           },
 735         { NFSERR_NOENT,         ENOENT          },
 736         { NFSERR_IO,            EIO             },
 737         { NFSERR_NXIO,          ENXIO           },
 738         { NFSERR_ACCES,         EACCES          },
 739         { NFSERR_EXIST,         EEXIST          },
 740         { NFSERR_NODEV,         ENODEV          },
 741         { NFSERR_NOTDIR,        ENOTDIR         },
 742         { NFSERR_ISDIR,         EISDIR          },
 743         { NFSERR_INVAL,         EINVAL          },
 744         { NFSERR_FBIG,          EFBIG           },
 745         { NFSERR_NOSPC,         ENOSPC          },
 746         { NFSERR_ROFS,          EROFS           },
 747         { NFSERR_NAMETOOLONG,   ENAMETOOLONG    },
 748         { NFSERR_NOTEMPTY,      ENOTEMPTY       },
 749         { NFSERR_DQUOT,         EDQUOT          },
 750         { NFSERR_STALE,         ESTALE          },
 751 #ifdef EWFLUSH
 752         { NFSERR_WFLUSH,        EWFLUSH         },
 753 #endif
 754         { -1,                   EIO             }
 755 };
 756 
 757 static int nfs_stat_to_errno(int stat)
     /* [previous][next][first][last][top][bottom][index][help] */
 758 {
 759         int i;
 760 
 761         for (i = 0; nfs_errtbl[i].stat != -1; i++) {
 762                 if (nfs_errtbl[i].stat == stat)
 763                         return nfs_errtbl[i].errno;
 764         }
 765         printk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
 766         return nfs_errtbl[i].errno;
 767 }
 768 

/* [previous][next][first][last][top][bottom][index][help] */