home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / nfs / dir.c next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  15.4 KB  |  607 lines

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