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

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