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 / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-06  |  7.0 KB  |  280 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.  *  Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
  9.  *  experimental NFS changes. Modularisation taken straight from SYS5 fs.
  10.  */
  11.  
  12. #ifdef MODULE
  13. #include <linux/module.h>
  14. #include <linux/version.h>
  15. #else
  16. #define MOD_INC_USE_COUNT
  17. #define MOD_DEC_USE_COUNT
  18. #endif
  19.  
  20. #include <asm/system.h>
  21. #include <asm/segment.h>
  22.  
  23. #include <linux/sched.h>
  24. #include <linux/nfs_fs.h>
  25. #include <linux/kernel.h>
  26. #include <linux/mm.h>
  27. #include <linux/string.h>
  28. #include <linux/stat.h>
  29. #include <linux/errno.h>
  30. #include <linux/locks.h>
  31.  
  32. extern int close_fp(struct file *filp);
  33.  
  34. static int nfs_notify_change(struct inode *, struct iattr *);
  35. static void nfs_put_inode(struct inode *);
  36. static void nfs_put_super(struct super_block *);
  37. static void nfs_statfs(struct super_block *, struct statfs *);
  38.  
  39. static struct super_operations nfs_sops = { 
  40.     NULL,            /* read inode */
  41.     nfs_notify_change,    /* notify change */
  42.     NULL,            /* write inode */
  43.     nfs_put_inode,        /* put inode */
  44.     nfs_put_super,        /* put superblock */
  45.     NULL,            /* write superblock */
  46.     nfs_statfs,        /* stat filesystem */
  47.     NULL
  48. };
  49.  
  50. static void nfs_put_inode(struct inode * inode)
  51. {
  52.     clear_inode(inode);
  53. }
  54.  
  55. void nfs_put_super(struct super_block *sb)
  56. {
  57.     close_fp(sb->u.nfs_sb.s_server.file);
  58.     lock_super(sb);
  59.     sb->s_dev = 0;
  60.     unlock_super(sb);
  61.     MOD_DEC_USE_COUNT;
  62. }
  63.  
  64. /*
  65.  * The way this works is that the mount process passes a structure
  66.  * in the data argument which contains an open socket to the NFS
  67.  * server and the root file handle obtained from the server's mount
  68.  * daemon.  We stash theses away in the private superblock fields.
  69.  * Later we can add other mount parameters like caching values.
  70.  */
  71.  
  72. struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
  73.                    int silent)
  74. {
  75.     struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
  76.     struct nfs_server *server;
  77.     unsigned int fd;
  78.     struct file *filp;
  79.     dev_t dev = sb->s_dev;
  80.  
  81.     MOD_INC_USE_COUNT;
  82.     if (!data) {
  83.         printk("nfs_read_super: missing data argument\n");
  84.         sb->s_dev = 0;
  85.         MOD_DEC_USE_COUNT;
  86.         return NULL;
  87.     }
  88.     fd = data->fd;
  89.     if (data->version != NFS_MOUNT_VERSION) {
  90.         printk("nfs warning: mount version %s than kernel\n",
  91.             data->version < NFS_MOUNT_VERSION ? "older" : "newer");
  92.     }
  93.     if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {
  94.         printk("nfs_read_super: invalid file descriptor\n");
  95.         sb->s_dev = 0;
  96.         MOD_DEC_USE_COUNT;
  97.         return NULL;
  98.     }
  99.     if (!S_ISSOCK(filp->f_inode->i_mode)) {
  100.         printk("nfs_read_super: not a socket\n");
  101.         sb->s_dev = 0;
  102.         MOD_DEC_USE_COUNT;
  103.         return NULL;
  104.     }
  105.     filp->f_count++;
  106.     lock_super(sb);
  107.     sb->s_blocksize = 1024; /* XXX */
  108.     sb->s_blocksize_bits = 10;
  109.     sb->s_magic = NFS_SUPER_MAGIC;
  110.     sb->s_dev = dev;
  111.     sb->s_op = &nfs_sops;
  112.     server = &sb->u.nfs_sb.s_server;
  113.     server->file = filp;
  114.     server->lock = 0;
  115.     server->wait = NULL;
  116.     server->flags = data->flags;
  117.     server->rsize = data->rsize;
  118.     if (server->rsize <= 0)
  119.         server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  120.     else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  121.         server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  122.     server->wsize = data->wsize;
  123.     if (server->wsize <= 0)
  124.         server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
  125.     else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
  126.         server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
  127.     server->timeo = data->timeo*HZ/10;
  128.     server->retrans = data->retrans;
  129.     server->acregmin = data->acregmin*HZ;
  130.     server->acregmax = data->acregmax*HZ;
  131.     server->acdirmin = data->acdirmin*HZ;
  132.     server->acdirmax = data->acdirmax*HZ;
  133.     strcpy(server->hostname, data->hostname);
  134.     sb->u.nfs_sb.s_root = data->root;
  135.     unlock_super(sb);
  136.     if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
  137.         sb->s_dev = 0;
  138.         printk("nfs_read_super: get root inode failed\n");
  139.         MOD_DEC_USE_COUNT;
  140.         return NULL;
  141.     }
  142.     return sb;
  143. }
  144.  
  145. void nfs_statfs(struct super_block *sb, struct statfs *buf)
  146. {
  147.     int error;
  148.     struct nfs_fsinfo res;
  149.  
  150.     put_fs_long(NFS_SUPER_MAGIC, &buf->f_type);
  151.     error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
  152.         &res);
  153.     if (error) {
  154.         printk("nfs_statfs: statfs error = %d\n", -error);
  155.         res.bsize = res.blocks = res.bfree = res.bavail = 0;
  156.     }
  157.     put_fs_long(res.bsize, &buf->f_bsize);
  158.     put_fs_long(res.blocks, &buf->f_blocks);
  159.     put_fs_long(res.bfree, &buf->f_bfree);
  160.     put_fs_long(res.bavail, &buf->f_bavail);
  161.     put_fs_long(0, &buf->f_files);
  162.     put_fs_long(0, &buf->f_ffree);
  163.     /* We should really try to interrogate the remote server to find
  164.        its maximum name length here */
  165.     put_fs_long(NAME_MAX, &buf->f_namelen);
  166. }
  167.  
  168. /*
  169.  * This is our own version of iget that looks up inodes by file handle
  170.  * instead of inode number.  We use this technique instead of using
  171.  * the vfs read_inode function because there is no way to pass the
  172.  * file handle or current attributes into the read_inode function.
  173.  * We just have to be careful not to subvert iget's special handling
  174.  * of mount points.
  175.  */
  176.  
  177. struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
  178.             struct nfs_fattr *fattr)
  179. {
  180.     struct nfs_fattr newfattr;
  181.     int error;
  182.     struct inode *inode;
  183.  
  184.     if (!sb) {
  185.         printk("nfs_fhget: super block is NULL\n");
  186.         return NULL;
  187.     }
  188.     if (!fattr) {
  189.         error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
  190.             &newfattr);
  191.         if (error) {
  192.             printk("nfs_fhget: getattr error = %d\n", -error);
  193.             return NULL;
  194.         }
  195.         fattr = &newfattr;
  196.     }
  197.     if (!(inode = iget(sb, fattr->fileid))) {
  198.         printk("nfs_fhget: iget failed\n");
  199.         return NULL;
  200.     }
  201.     if (inode->i_dev == sb->s_dev) {
  202.         if (inode->i_ino != fattr->fileid) {
  203.             printk("nfs_fhget: unexpected inode from iget\n");
  204.             return inode;
  205.         }
  206.         *NFS_FH(inode) = *fhandle;
  207.         nfs_refresh_inode(inode, fattr);
  208.     }
  209.     return inode;
  210. }
  211.  
  212. int nfs_notify_change(struct inode *inode, struct iattr *attr)
  213. {
  214.     struct nfs_sattr sattr;
  215.     struct nfs_fattr fattr;
  216.     int error;
  217.  
  218.     if (attr->ia_valid & ATTR_MODE) 
  219.         sattr.mode = attr->ia_mode;
  220.     else
  221.         sattr.mode = (unsigned) -1;
  222.  
  223.     if (attr->ia_valid & ATTR_UID)
  224.         sattr.uid = attr->ia_uid;
  225.     else
  226.         sattr.uid = (unsigned) -1;
  227.  
  228.     if (attr->ia_valid & ATTR_GID)
  229.         sattr.gid = attr->ia_gid;
  230.     else
  231.         sattr.gid = (unsigned) -1;
  232.  
  233.     if (attr->ia_valid & ATTR_SIZE)
  234.         sattr.size = S_ISREG(inode->i_mode) ? attr->ia_size : -1;
  235.     else
  236.         sattr.size = (unsigned) -1;
  237.  
  238.     if (attr->ia_valid & ATTR_MTIME) {
  239.         sattr.mtime.seconds = attr->ia_mtime;
  240.         sattr.mtime.useconds = 0;
  241.     } else 
  242.         sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1;
  243.  
  244.     if (attr->ia_valid & ATTR_ATIME) {
  245.         sattr.atime.seconds = attr->ia_atime;
  246.         sattr.atime.useconds = 0;
  247.     } else
  248.         sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1;
  249.  
  250.     error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),
  251.         &sattr, &fattr);
  252.     if (!error)
  253.         nfs_refresh_inode(inode, &fattr);
  254.     inode->i_dirt = 0;
  255.     return error;
  256. }
  257.  
  258. #ifdef MODULE
  259.  
  260. /* Every kernel module contains stuff like this. */
  261.  
  262. char kernel_version[] = UTS_RELEASE;
  263.  
  264. static struct file_system_type nfs_fs_type = {
  265.     nfs_read_super, "nfs", 0, NULL
  266. };
  267.  
  268. int init_module(void)
  269. {
  270.     register_filesystem(&nfs_fs_type);
  271.     return 0;
  272. }
  273.  
  274. void cleanup_module(void)
  275. {
  276.     unregister_filesystem(&nfs_fs_type);
  277. }
  278.  
  279. #endif
  280.