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 / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  6.2 KB  |  234 lines

  1. /*
  2.  *  linux/fs/nfs/inode.c
  3.  *
  4.  *  Copyright (C) 1992  Rick Sladkey
  5.  *
  6.  *  nfs inode and superblock handling functions
  7.  */
  8.  
  9. #include <asm/system.h>
  10. #include <asm/segment.h>
  11.  
  12. #include <linux/sched.h>
  13. #include <linux/nfs_fs.h>
  14. #include <linux/kernel.h>
  15. #include <linux/mm.h>
  16. #include <linux/string.h>
  17. #include <linux/stat.h>
  18. #include <linux/errno.h>
  19. #include <linux/locks.h>
  20.  
  21. extern int close_fp(struct file *filp, unsigned int fd);
  22.  
  23. static int nfs_notify_change(int, struct inode *);
  24. static void nfs_put_inode(struct inode *);
  25. static void nfs_put_super(struct super_block *);
  26. static void nfs_statfs(struct super_block *, struct statfs *);
  27.  
  28. static struct super_operations nfs_sops = { 
  29.     NULL,            /* read inode */
  30.     nfs_notify_change,    /* notify change */
  31.     NULL,            /* write inode */
  32.     nfs_put_inode,        /* put inode */
  33.     nfs_put_super,        /* put superblock */
  34.     NULL,            /* write superblock */
  35.     nfs_statfs,        /* stat filesystem */
  36.     NULL
  37. };
  38.  
  39. static void nfs_put_inode(struct inode * inode)
  40. {
  41.     clear_inode(inode);
  42. }
  43.  
  44. void nfs_put_super(struct super_block *sb)
  45. {
  46.         /* No locks should be open on this, so 0 should be safe as a fd. */
  47.     close_fp(sb->u.nfs_sb.s_server.file, 0);
  48.     lock_super(sb);
  49.     sb->s_dev = 0;
  50.     unlock_super(sb);
  51. }
  52.  
  53. /*
  54.  * The way this works is that the mount process passes a structure
  55.  * in the data argument which contains an open socket to the NFS
  56.  * server and the root file handle obtained from the server's mount
  57.  * daemon.  We stash theses away in the private superblock fields.
  58.  * Later we can add other mount parameters like caching values.
  59.  */
  60.  
  61. struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
  62.                    int silent)
  63. {
  64.     struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
  65.     struct nfs_server *server;
  66.     unsigned int fd;
  67.     struct file *filp;
  68.     dev_t dev = sb->s_dev;
  69.  
  70.     if (!data) {
  71.         printk("nfs_read_super: missing data argument\n");
  72.         sb->s_dev = 0;
  73.         return NULL;
  74.     }
  75.     fd = data->fd;
  76.     if (data->version != NFS_MOUNT_VERSION) {
  77.         printk("nfs warning: mount version %s than kernel\n",
  78.             data->version < NFS_MOUNT_VERSION ? "older" : "newer");
  79.     }
  80.     if (fd >= NR_OPEN || !(filp = current->filp[fd])) {
  81.         printk("nfs_read_super: invalid file descriptor\n");
  82.         sb->s_dev = 0;
  83.         return NULL;
  84.     }
  85.     if (!S_ISSOCK(filp->f_inode->i_mode)) {
  86.         printk("nfs_read_super: not a socket\n");
  87.         sb->s_dev = 0;
  88.         return NULL;
  89.     }
  90.     filp->f_count++;
  91.     lock_super(sb);
  92.     sb->s_blocksize = 1024; /* XXX */
  93.     sb->s_blocksize_bits = 10;
  94.     sb->s_magic = NFS_SUPER_MAGIC;
  95.     sb->s_dev = dev;
  96.     sb->s_op = &nfs_sops;
  97.     server = &sb->u.nfs_sb.s_server;
  98.     server->file = filp;
  99.     server->lock = 0;
  100.     server->wait = NULL;
  101.     server->flags = data->flags;
  102.     server->rsize = data->rsize;
  103.     if (server->rsize <= 0)
  104.         server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  105.     else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  106.         server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  107.     server->wsize = data->wsize;
  108.     if (server->wsize <= 0)
  109.         server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  110.     else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  111.         server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  112.     server->timeo = data->timeo*HZ/10;
  113.     server->retrans = data->retrans;
  114.     server->acregmin = data->acregmin*HZ;
  115.     server->acregmax = data->acregmax*HZ;
  116.     server->acdirmin = data->acdirmin*HZ;
  117.     server->acdirmax = data->acdirmax*HZ;
  118.     strcpy(server->hostname, data->hostname);
  119.     sb->u.nfs_sb.s_root = data->root;
  120.     unlock_super(sb);
  121.     if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
  122.         sb->s_dev = 0;
  123.         printk("nfs_read_super: get root inode failed\n");
  124.         return NULL;
  125.     }
  126.     return sb;
  127. }
  128.  
  129. void nfs_statfs(struct super_block *sb, struct statfs *buf)
  130. {
  131.     int error;
  132.     struct nfs_fsinfo res;
  133.  
  134.     put_fs_long(NFS_SUPER_MAGIC, &buf->f_type);
  135.     error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
  136.         &res);
  137.     if (error) {
  138.         printk("nfs_statfs: statfs error = %d\n", -error);
  139.         res.bsize = res.blocks = res.bfree = res.bavail = 0;
  140.     }
  141.     put_fs_long(res.bsize, &buf->f_bsize);
  142.     put_fs_long(res.blocks, &buf->f_blocks);
  143.     put_fs_long(res.bfree, &buf->f_bfree);
  144.     put_fs_long(res.bavail, &buf->f_bavail);
  145.     put_fs_long(0, &buf->f_files);
  146.     put_fs_long(0, &buf->f_ffree);
  147.     /* We should really try to interrogate the remote server to find
  148.        it's maximum name length here */
  149.     put_fs_long(NAME_MAX, &buf->f_namelen);
  150. }
  151.  
  152. /*
  153.  * This is our own version of iget that looks up inodes by file handle
  154.  * instead of inode number.  We use this technique instead of using
  155.  * the vfs read_inode function because there is no way to pass the
  156.  * file handle or current attributes into the read_inode function.
  157.  * We just have to be careful not to subvert iget's special handling
  158.  * of mount points.
  159.  */
  160.  
  161. struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
  162.             struct nfs_fattr *fattr)
  163. {
  164.     struct nfs_fattr newfattr;
  165.     int error;
  166.     struct inode *inode;
  167.  
  168.     if (!sb) {
  169.         printk("nfs_fhget: super block is NULL\n");
  170.         return NULL;
  171.     }
  172.     if (!fattr) {
  173.         error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
  174.             &newfattr);
  175.         if (error) {
  176.             printk("nfs_fhget: getattr error = %d\n", -error);
  177.             return NULL;
  178.         }
  179.         fattr = &newfattr;
  180.     }
  181.     if (!(inode = iget(sb, fattr->fileid))) {
  182.         printk("nfs_fhget: iget failed\n");
  183.         return NULL;
  184.     }
  185.     if (inode->i_dev == sb->s_dev) {
  186.         if (inode->i_ino != fattr->fileid) {
  187.             printk("nfs_fhget: unexpected inode from iget\n");
  188.             return inode;
  189.         }
  190.         *NFS_FH(inode) = *fhandle;
  191.         nfs_refresh_inode(inode, fattr);
  192.     }
  193.     return inode;
  194. }
  195.  
  196. int nfs_notify_change(int flags, struct inode *inode)
  197. {
  198.     struct nfs_sattr sattr;
  199.     struct nfs_fattr fattr;
  200.     int error;
  201.  
  202.     if (flags & NOTIFY_MODE)
  203.         sattr.mode = inode->i_mode;
  204.     else
  205.         sattr.mode = (unsigned) -1;
  206.     if (flags & NOTIFY_UIDGID) {
  207.         sattr.uid = inode->i_uid;
  208.         sattr.gid = inode->i_gid;
  209.     }
  210.     else
  211.         sattr.uid = sattr.gid = (unsigned) -1;
  212.     if (flags & NOTIFY_SIZE)
  213.         sattr.size = S_ISREG(inode->i_mode) ? inode->i_size : -1;
  214.     else
  215.         sattr.size = (unsigned) -1;
  216.     if (flags & NOTIFY_TIME) {
  217.         sattr.mtime.seconds = inode->i_mtime;
  218.         sattr.mtime.useconds = 0;
  219.         sattr.atime.seconds = inode->i_atime;
  220.         sattr.atime.useconds = 0;
  221.     }
  222.     else {
  223.         sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1;
  224.         sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1;
  225.     }
  226.     error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),
  227.         &sattr, &fattr);
  228.     if (!error)
  229.         nfs_refresh_inode(inode, &fattr);
  230.     inode->i_dirt = 0;
  231.     return error;
  232. }
  233.  
  234.