root/fs/nfs/dir.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_dir_read
  2. nfs_readdir
  3. nfs_lookup_cache_index
  4. nfs_lookup_cache_lookup
  5. nfs_lookup_cache_add
  6. nfs_lookup_cache_remove
  7. nfs_lookup_cache_refresh
  8. nfs_lookup
  9. nfs_create
  10. nfs_mknod
  11. nfs_mkdir
  12. nfs_rmdir
  13. nfs_unlink
  14. nfs_symlink
  15. nfs_link
  16. nfs_rename
  17. nfs_refresh_inode

   1 /*
   2  *  linux/fs/nfs/dir.c
   3  *
   4  *  Copyright (C) 1992  Rick Sladkey
   5  *
   6  *  nfs directory handling functions
   7  */
   8 
   9 #include <linux/sched.h>
  10 #include <linux/errno.h>
  11 #include <linux/stat.h>
  12 #include <linux/nfs_fs.h>
  13 #include <linux/fcntl.h>
  14 #include <linux/string.h>
  15 #include <linux/kernel.h>
  16 #include <linux/mm.h>
  17 
  18 #include <asm/segment.h>        /* for fs functions */
  19 
  20 static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
  21                         int count);
  22 static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
  23 static int nfs_lookup(struct inode *dir, const char *name, int len,
  24                       struct inode **result);
  25 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
  26                       struct inode **result);
  27 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode);
  28 static int nfs_rmdir(struct inode *dir, const char *name, int len);
  29 static int nfs_unlink(struct inode *dir, const char *name, int len);
  30 static int nfs_symlink(struct inode *inode, const char *name, int len,
  31                        const char *symname);
  32 static int nfs_link(struct inode *oldinode, struct inode *dir,
  33                     const char *name, int len);
  34 static int nfs_mknod(struct inode *dir, const char *name, int len, int mode,
  35                      int rdev);
  36 static int nfs_rename(struct inode *old_dir, const char *old_name,
  37                       int old_len, struct inode *new_dir, const char *new_name,
  38                       int new_len);
  39 
  40 static struct file_operations nfs_dir_operations = {
  41         NULL,                   /* lseek - default */
  42         nfs_dir_read,           /* read - bad */
  43         NULL,                   /* write - bad */
  44         nfs_readdir,            /* readdir */
  45         NULL,                   /* select - default */
  46         NULL,                   /* ioctl - default */
  47         NULL,                   /* mmap */
  48         NULL,                   /* no special open code */
  49         NULL                    /* no special release code */
  50 };
  51 
  52 struct inode_operations nfs_dir_inode_operations = {
  53         &nfs_dir_operations,    /* default directory file-ops */
  54         nfs_create,             /* create */
  55         nfs_lookup,             /* lookup */
  56         nfs_link,               /* link */
  57         nfs_unlink,             /* unlink */
  58         nfs_symlink,            /* symlink */
  59         nfs_mkdir,              /* mkdir */
  60         nfs_rmdir,              /* rmdir */
  61         nfs_mknod,              /* mknod */
  62         nfs_rename,             /* rename */
  63         NULL,                   /* readlink */
  64         NULL,                   /* follow_link */
  65         NULL,                   /* bmap */
  66         NULL,                   /* truncate */
  67         NULL                    /* permission */
  68 };
  69 
  70 static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
  71                         int count)
  72 {
  73         return -EISDIR;
  74 }
  75 
  76 /*
  77  * We need to do caching of directory entries to prevent an
  78  * incredible amount of RPC traffic.  Only the most recent open
  79  * directory is cached.  This seems sufficient for most purposes.
  80  * Technically, we ought to flush the cache on close but this is
  81  * not a problem in practice.
  82  */
  83 
  84 static int nfs_readdir(struct inode *inode, struct file *filp,
     /* [previous][next][first][last][top][bottom][index][help] */
  85                        struct dirent *dirent, int count)
  86 {
  87         static int c_dev = 0;
  88         static int c_ino;
  89         static int c_size;
  90         static struct nfs_entry *c_entry = NULL;
  91 
  92         int result;
  93         int i;
  94         struct nfs_entry *entry;
  95 
  96         if (!inode || !S_ISDIR(inode->i_mode)) {
  97                 printk("nfs_readdir: inode is NULL or not a directory\n");
  98                 return -EBADF;
  99         }
 100 
 101         /* initialize cache memory if it hasn't been used before */
 102 
 103         if (c_entry == NULL) {
 104                 i = sizeof (struct nfs_entry)*NFS_READDIR_CACHE_SIZE;
 105                 c_entry = (struct nfs_entry *) kmalloc(i, GFP_KERNEL);
 106                 for (i = 0; i < NFS_READDIR_CACHE_SIZE; i++) {
 107                         c_entry[i].name = (char *) kmalloc(NFS_MAXNAMLEN + 1,
 108                                 GFP_KERNEL);
 109                 }
 110         }
 111         entry = NULL;
 112 
 113         /* try to find it in the cache */
 114 
 115         if (inode->i_dev == c_dev && inode->i_ino == c_ino) {
 116                 for (i = 0; i < c_size; i++) {
 117                         if (filp->f_pos == c_entry[i].cookie) {
 118                                 if (i == c_size - 1) {
 119                                         if (c_entry[i].eof)
 120                                                 return 0;
 121                                 }
 122                                 else
 123                                         entry = c_entry + i + 1;
 124                                 break;
 125                         }
 126                 }
 127         }
 128 
 129         /* if we didn't find it in the cache, revert to an nfs call */
 130 
 131         if (!entry) {
 132                 result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode),
 133                         filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
 134                 if (result < 0) {
 135                         c_dev = 0;
 136                         return result;
 137                 }
 138                 if (result > 0) {
 139                         c_dev = inode->i_dev;
 140                         c_ino = inode->i_ino;
 141                         c_size = result;
 142                         entry = c_entry + 0;
 143                 }
 144         }
 145 
 146         /* if we found it in the cache or from an nfs call, return results */
 147 
 148         if (entry) {
 149                 i = strlen(entry->name);
 150                 memcpy_tofs(dirent->d_name, entry->name, i + 1);
 151                 put_fs_long(entry->fileid, &dirent->d_ino);
 152                 put_fs_word(i, &dirent->d_reclen);
 153                 filp->f_pos = entry->cookie;
 154                 return i;
 155         }
 156         return 0;
 157 }
 158 
 159 /*
 160  * Lookup caching is a big win for performance but this is just
 161  * a trial to see how well it works on a small scale.
 162  * For example, bash does a lookup on ".." 13 times for each path
 163  * element when running pwd.  Yes, hard to believe but true.
 164  * Try pwd in a filesystem mounted with noac.
 165  *
 166  * It trades a little cpu time and memory for a lot of network bandwidth.
 167  * Since the cache is not hashed yet, it is a good idea not to make it too
 168  * large because every lookup looks through the entire cache even
 169  * though most of them will fail.
 170  */
 171 
 172 static struct nfs_lookup_cache_entry {
 173         int dev;
 174         int inode;
 175         char filename[NFS_MAXNAMLEN + 1];
 176         struct nfs_fh fhandle;
 177         struct nfs_fattr fattr;
 178         int expiration_date;
 179 } nfs_lookup_cache[NFS_LOOKUP_CACHE_SIZE];
 180 
 181 static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 182                                                              char *filename)
 183 {
 184         struct nfs_lookup_cache_entry *entry;
 185         int i;
 186 
 187         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 188                 entry = nfs_lookup_cache + i;
 189                 if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
 190                     && !strncmp(filename, entry->filename, NFS_MAXNAMLEN))
 191                         return entry;
 192         }
 193         return NULL;
 194 }
 195 
 196 static int nfs_lookup_cache_lookup(struct inode *dir, char *filename,
     /* [previous][next][first][last][top][bottom][index][help] */
 197                                    struct nfs_fh *fhandle,
 198                                    struct nfs_fattr *fattr)
 199 {
 200         static int nfs_lookup_cache_in_use = 0;
 201 
 202         struct nfs_lookup_cache_entry *entry;
 203 
 204         if (!nfs_lookup_cache_in_use) {
 205                 memset(nfs_lookup_cache, 0, sizeof(nfs_lookup_cache));
 206                 nfs_lookup_cache_in_use = 1;
 207         }
 208         if ((entry = nfs_lookup_cache_index(dir, filename))) {
 209                 if (jiffies > entry->expiration_date) {
 210                         entry->dev = 0;
 211                         return 0;
 212                 }
 213                 *fhandle = entry->fhandle;
 214                 *fattr = entry->fattr;
 215                 return 1;
 216         }
 217         return 0;
 218 }
 219 
 220 static void nfs_lookup_cache_add(struct inode *dir, char *filename,
     /* [previous][next][first][last][top][bottom][index][help] */
 221                                  struct nfs_fh *fhandle,
 222                                  struct nfs_fattr *fattr)
 223 {
 224         static int nfs_lookup_cache_pos = 0;
 225         struct nfs_lookup_cache_entry *entry;
 226 
 227         /* compensate for bug in SGI NFS server */
 228         if (fattr->size == -1 || fattr->uid == -1 || fattr->gid == -1
 229             || fattr->atime.seconds == -1 || fattr->mtime.seconds == -1)
 230                 return;
 231         if (!(entry = nfs_lookup_cache_index(dir, filename))) {
 232                 entry = nfs_lookup_cache + nfs_lookup_cache_pos++;
 233                 if (nfs_lookup_cache_pos == NFS_LOOKUP_CACHE_SIZE)
 234                         nfs_lookup_cache_pos = 0;
 235         }
 236         entry->dev = dir->i_dev;
 237         entry->inode = dir->i_ino;
 238         strcpy(entry->filename, filename);
 239         entry->fhandle = *fhandle;
 240         entry->fattr = *fattr;
 241         entry->expiration_date = jiffies + (S_ISDIR(fattr->mode)
 242                 ? NFS_SERVER(dir)->acdirmax : NFS_SERVER(dir)->acregmax);
 243 }
 244 
 245 static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
 246                                     char *filename)
 247 {
 248         struct nfs_lookup_cache_entry *entry;
 249         int dev;
 250         int fileid;
 251         int i;
 252 
 253         if (inode) {
 254                 dev = inode->i_dev;
 255                 fileid = inode->i_ino;
 256         }
 257         else if ((entry = nfs_lookup_cache_index(dir, filename))) {
 258                 dev = entry->dev;
 259                 fileid = entry->fattr.fileid;
 260         }
 261         else
 262                 return;
 263         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 264                 entry = nfs_lookup_cache + i;
 265                 if (entry->dev == dev && entry->fattr.fileid == fileid)
 266                         entry->dev = 0;
 267         }
 268 }
 269 
 270 static void nfs_lookup_cache_refresh(struct inode *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 271                                      struct nfs_fattr *fattr)
 272 {
 273         struct nfs_lookup_cache_entry *entry;
 274         int dev = file->i_dev;
 275         int fileid = file->i_ino;
 276         int i;
 277 
 278         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 279                 entry = nfs_lookup_cache + i;
 280                 if (entry->dev == dev && entry->fattr.fileid == fileid)
 281                         entry->fattr = *fattr;
 282         }
 283 }
 284 
 285 static int nfs_lookup(struct inode *dir, const char *name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 286                       struct inode **result)
 287 {
 288         char filename[NFS_MAXNAMLEN + 1];
 289         struct nfs_fh fhandle;
 290         struct nfs_fattr fattr;
 291         int error;
 292 
 293         *result = NULL;
 294         if (!dir || !S_ISDIR(dir->i_mode)) {
 295                 printk("nfs_lookup: inode is NULL or not a directory\n");
 296                 iput(dir);
 297                 return -ENOENT;
 298         }
 299         if (len > NFS_MAXNAMLEN) {
 300                 iput(dir);
 301                 return -ENAMETOOLONG;
 302         }
 303         memcpy_fromfs(filename, (char *) name, len);
 304         filename[len] = '\0';
 305         if (len == 1 && filename[0] == '.') { /* cheat for "." */
 306                 *result = dir;
 307                 return 0;
 308         }
 309         if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
 310             || !nfs_lookup_cache_lookup(dir, filename, &fhandle, &fattr)) {
 311                 if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
 312                     filename, &fhandle, &fattr))) {
 313                         iput(dir);
 314                         return error;
 315                 }
 316                 nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
 317         }
 318         if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
 319                 iput(dir);
 320                 return -EACCES;
 321         }
 322         iput(dir);
 323         return 0;
 324 }
 325 
 326 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 327                       struct inode **result)
 328 {
 329         char filename[NFS_MAXNAMLEN + 1];
 330         struct nfs_sattr sattr;
 331         struct nfs_fattr fattr;
 332         struct nfs_fh fhandle;
 333         int error;
 334 
 335         *result = NULL;
 336         if (!dir || !S_ISDIR(dir->i_mode)) {
 337                 printk("nfs_create: inode is NULL or not a directory\n");
 338                 iput(dir);
 339                 return -ENOENT;
 340         }
 341         if (len > NFS_MAXNAMLEN) {
 342                 iput(dir);
 343                 return -ENAMETOOLONG;
 344         }
 345         memcpy_fromfs(filename, (char *) name, len);
 346         filename[len] = '\0';
 347         sattr.mode = mode;
 348         sattr.uid = sattr.gid = sattr.size = -1;
 349         sattr.atime.seconds = sattr.mtime.seconds = -1;
 350         if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
 351                 filename, &sattr, &fhandle, &fattr))) {
 352                 iput(dir);
 353                 return error;
 354         }
 355         if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
 356                 iput(dir);
 357                 return -EACCES;
 358         }
 359         nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
 360         iput(dir);
 361         return 0;
 362 }
 363 
 364 static int nfs_mknod(struct inode *dir, const char *name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 365                      int mode, int rdev)
 366 {
 367         char filename[NFS_MAXNAMLEN + 1];
 368         struct nfs_sattr sattr;
 369         struct nfs_fattr fattr;
 370         struct nfs_fh fhandle;
 371         int error;
 372 
 373         if (!dir || !S_ISDIR(dir->i_mode)) {
 374                 printk("nfs_mknod: inode is NULL or not a directory\n");
 375                 iput(dir);
 376                 return -ENOENT;
 377         }
 378         if (len > NFS_MAXNAMLEN) {
 379                 iput(dir);
 380                 return -ENAMETOOLONG;
 381         }
 382         memcpy_fromfs(filename, (char *) name, len);
 383         filename[len] = '\0';
 384         sattr.mode = mode;
 385         sattr.uid = sattr.gid = -1;
 386         if (S_ISCHR(mode) || S_ISBLK(mode))
 387                 sattr.size = rdev; /* get out your barf bag */
 388         else
 389                 sattr.size = -1;
 390         sattr.atime.seconds = sattr.mtime.seconds = -1;
 391         error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
 392                 filename, &sattr, &fhandle, &fattr);
 393         if (!error)
 394                 nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
 395         iput(dir);
 396         return error;
 397 }
 398 
 399 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 400 {
 401         char filename[NFS_MAXNAMLEN + 1];
 402         struct nfs_sattr sattr;
 403         struct nfs_fattr fattr;
 404         struct nfs_fh fhandle;
 405         int error;
 406 
 407         if (!dir || !S_ISDIR(dir->i_mode)) {
 408                 printk("nfs_mkdir: inode is NULL or not a directory\n");
 409                 iput(dir);
 410                 return -ENOENT;
 411         }
 412         if (len > NFS_MAXNAMLEN) {
 413                 iput(dir);
 414                 return -ENAMETOOLONG;
 415         }
 416         memcpy_fromfs(filename, (char *) name, len);
 417         filename[len] = '\0';
 418         sattr.mode = mode;
 419         sattr.uid = sattr.gid = sattr.size = -1;
 420         sattr.atime.seconds = sattr.mtime.seconds = -1;
 421         error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
 422                 filename, &sattr, &fhandle, &fattr);
 423         if (!error)
 424                 nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
 425         iput(dir);
 426         return error;
 427 }
 428 
 429 static int nfs_rmdir(struct inode *dir, const char *name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 430 {
 431         char filename[NFS_MAXNAMLEN + 1];
 432         int error;
 433 
 434         if (!dir || !S_ISDIR(dir->i_mode)) {
 435                 printk("nfs_rmdir: inode is NULL or not a directory\n");
 436                 iput(dir);
 437                 return -ENOENT;
 438         }
 439         if (len > NFS_MAXNAMLEN) {
 440                 iput(dir);
 441                 return -ENAMETOOLONG;
 442         }
 443         memcpy_fromfs(filename, (char *) name, len);
 444         filename[len] = '\0';
 445         error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), filename);
 446         if (!error)
 447                 nfs_lookup_cache_remove(dir, NULL, filename);
 448         iput(dir);
 449         return error;
 450 }
 451 
 452 static int nfs_unlink(struct inode *dir, const char *name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454         char filename[NFS_MAXNAMLEN + 1];
 455         int error;
 456 
 457         if (!dir || !S_ISDIR(dir->i_mode)) {
 458                 printk("nfs_unlink: inode is NULL or not a directory\n");
 459                 iput(dir);
 460                 return -ENOENT;
 461         }
 462         if (len > NFS_MAXNAMLEN) {
 463                 iput(dir);
 464                 return -ENAMETOOLONG;
 465         }
 466         memcpy_fromfs(filename, (char *) name, len);
 467         filename[len] = '\0';
 468         error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), filename);
 469         if (!error)
 470                 nfs_lookup_cache_remove(dir, NULL, filename);
 471         iput(dir);
 472         return error;
 473 }
 474 
 475 static int nfs_symlink(struct inode *dir, const char *name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 476                        const char *symname)
 477 {
 478         char filename[NFS_MAXNAMLEN + 1];
 479         char *symfilename;
 480         struct nfs_sattr sattr;
 481         int error;
 482         int i;
 483         int c;
 484 
 485         if (!dir || !S_ISDIR(dir->i_mode)) {
 486                 printk("nfs_symlink: inode is NULL or not a directory\n");
 487                 iput(dir);
 488                 return -ENOENT;
 489         }
 490         if (len > NFS_MAXNAMLEN) {
 491                 iput(dir);
 492                 return -ENAMETOOLONG;
 493         }
 494         memcpy_fromfs(filename, (char *) name, len);
 495         filename[len] = '\0';
 496         symfilename = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
 497         for (i = 0; i < NFS_MAXPATHLEN && (c = get_fs_byte(symname++)); i++)
 498                 symfilename[i] = c;
 499         if (i == NFS_MAXPATHLEN && get_fs_byte(symname)) {
 500                 kfree_s(symfilename, NFS_MAXPATHLEN + 1);
 501                 iput(dir);
 502                 return -ENAMETOOLONG;
 503         }
 504         symfilename[i] = '\0';
 505         sattr.mode = S_IFLNK | 0777; /* SunOS 4.1.2 crashes without this! */
 506         sattr.uid = sattr.gid = sattr.size = -1;
 507         sattr.atime.seconds = sattr.mtime.seconds = -1;
 508         error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
 509                 filename, symfilename, &sattr);
 510         kfree_s(symfilename, NFS_MAXPATHLEN + 1);
 511         iput(dir);
 512         return error;
 513 }
 514 
 515 static int nfs_link(struct inode *oldinode, struct inode *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 516                     const char *name, int len)
 517 {
 518         char filename[NFS_MAXNAMLEN + 1];
 519         int error;
 520 
 521         if (!oldinode) {
 522                 printk("nfs_link: old inode is NULL\n");
 523                 iput(oldinode);
 524                 iput(dir);
 525                 return -ENOENT;
 526         }
 527         if (!dir || !S_ISDIR(dir->i_mode)) {
 528                 printk("nfs_link: dir is NULL or not a directory\n");
 529                 iput(oldinode);
 530                 iput(dir);
 531                 return -ENOENT;
 532         }
 533         if (len > NFS_MAXNAMLEN) {
 534                 iput(oldinode);
 535                 iput(dir);
 536                 return -ENAMETOOLONG;
 537         }
 538         memcpy_fromfs(filename, (char *) name, len);
 539         filename[len] = '\0';
 540         error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
 541                 NFS_FH(dir), filename);
 542         if (!error)
 543                 nfs_lookup_cache_remove(dir, oldinode, NULL);
 544         iput(oldinode);
 545         iput(dir);
 546         return error;
 547 }
 548 
 549 static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
     /* [previous][next][first][last][top][bottom][index][help] */
 550                       struct inode *new_dir, const char *new_name, int new_len)
 551 {
 552         char old_filename[NFS_MAXNAMLEN + 1];
 553         char new_filename[NFS_MAXNAMLEN + 1];
 554         int error;
 555 
 556         if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
 557                 printk("nfs_rename: old inode is NULL or not a directory\n");
 558                 iput(old_dir);
 559                 iput(new_dir);
 560                 return -ENOENT;
 561         }
 562         if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
 563                 printk("nfs_rename: new inode is NULL or not a directory\n");
 564                 iput(old_dir);
 565                 iput(new_dir);
 566                 return -ENOENT;
 567         }
 568         if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
 569                 iput(old_dir);
 570                 iput(new_dir);
 571                 return -ENAMETOOLONG;
 572         }
 573         memcpy_fromfs(old_filename, (char *) old_name, old_len);
 574         old_filename[old_len] = '\0';
 575         memcpy_fromfs(new_filename, (char *) new_name, new_len);
 576         new_filename[new_len] = '\0';
 577         error = nfs_proc_rename(NFS_SERVER(old_dir),
 578                 NFS_FH(old_dir), old_filename,
 579                 NFS_FH(new_dir), new_filename);
 580         if (!error)
 581                 nfs_lookup_cache_remove(old_dir, NULL, old_filename);
 582         iput(old_dir);
 583         iput(new_dir);
 584         return error;
 585 }
 586 
 587 /*
 588  * Many nfs protocol calls return the new file attributes after
 589  * an operation.  Here we update the inode to reflect the state
 590  * of the server's inode.
 591  */
 592 
 593 void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
     /* [previous][next][first][last][top][bottom][index][help] */
 594 {
 595         int was_empty;
 596 
 597         if (!inode || !fattr) {
 598                 printk("nfs_refresh_inode: inode or fattr is NULL\n");
 599                 return;
 600         }
 601         if (inode->i_ino != fattr->fileid) {
 602                 printk("nfs_refresh_inode: inode number mismatch\n");
 603                 return;
 604         }
 605         was_empty = inode->i_mode == 0;
 606         inode->i_mode = fattr->mode;
 607         inode->i_nlink = fattr->nlink;
 608         inode->i_uid = fattr->uid;
 609         inode->i_gid = fattr->gid;
 610         inode->i_size = fattr->size;
 611         inode->i_blksize = fattr->blocksize;
 612         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 613                 inode->i_rdev = fattr->rdev;
 614         else
 615                 inode->i_rdev = 0;
 616         inode->i_blocks = fattr->blocks;
 617         inode->i_atime = fattr->atime.seconds;
 618         inode->i_mtime = fattr->mtime.seconds;
 619         inode->i_ctime = fattr->ctime.seconds;
 620         if (was_empty) {
 621                 if (S_ISREG(inode->i_mode))
 622                         inode->i_op = &nfs_file_inode_operations;
 623                 else if (S_ISDIR(inode->i_mode))
 624                         inode->i_op = &nfs_dir_inode_operations;
 625                 else if (S_ISLNK(inode->i_mode))
 626                         inode->i_op = &nfs_symlink_inode_operations;
 627                 else if (S_ISCHR(inode->i_mode))
 628                         inode->i_op = &nfs_chrdev_inode_operations;
 629                 else if (S_ISBLK(inode->i_mode))
 630                         inode->i_op = &nfs_blkdev_inode_operations;
 631                 else if (S_ISFIFO(inode->i_mode)) {
 632                         inode->i_op = &nfs_fifo_inode_operations;
 633                         inode->i_pipe = 1;
 634                         PIPE_BASE(*inode) = NULL;
 635                         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 636                         PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
 637                 }
 638                 else
 639                         inode->i_op = NULL;
 640         }
 641         nfs_lookup_cache_refresh(inode, fattr);
 642 }
 643 

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