root/fs/nfs/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_put_inode
  2. nfs_put_super
  3. nfs_read_super
  4. nfs_statfs
  5. nfs_fhget
  6. nfs_notify_change

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         clear_inode(inode);
  42 }
  43 
  44 void nfs_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 

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