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
  7. init_module
  8. cleanup_module

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

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