home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / nfs / dir.c next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  15.6 KB  |  614 lines

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