root/fs/nfs/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_read_inode
  2. nfs_put_inode
  3. nfs_put_super
  4. nfs_read_super
  5. nfs_statfs
  6. nfs_fhget
  7. nfs_notify_change
  8. init_nfs_fs
  9. init_module
  10. 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  *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
  12  *  J.S.Peatfield@damtp.cam.ac.uk
  13  *
  14  */
  15 
  16 #include <linux/module.h>
  17 
  18 #include <linux/sched.h>
  19 #include <linux/nfs_fs.h>
  20 #include <linux/kernel.h>
  21 #include <linux/mm.h>
  22 #include <linux/string.h>
  23 #include <linux/stat.h>
  24 #include <linux/errno.h>
  25 #include <linux/locks.h>
  26 
  27 #include <asm/system.h>
  28 #include <asm/segment.h>
  29 
  30 extern int close_fp(struct file *filp);
  31 
  32 static int nfs_notify_change(struct inode *, struct iattr *);
  33 static void nfs_put_inode(struct inode *);
  34 static void nfs_put_super(struct super_block *);
  35 static void nfs_read_inode(struct inode *);
  36 static void nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
  37 
  38 static struct super_operations nfs_sops = { 
  39         nfs_read_inode,         /* read inode */
  40         nfs_notify_change,      /* notify change */
  41         NULL,                   /* write inode */
  42         nfs_put_inode,          /* put inode */
  43         nfs_put_super,          /* put superblock */
  44         NULL,                   /* write superblock */
  45         nfs_statfs,             /* stat filesystem */
  46         NULL
  47 };
  48 
  49 /*
  50  * The "read_inode" function doesn't actually do anything:
  51  * the real data is filled in later in nfs_fhget. Here we
  52  * just mark the cache times invalid, and zero out i_mode
  53  * (the latter makes "nfs_refresh_inode" do the right thing)
  54  */
  55 static void nfs_read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         inode->i_mode = 0;
  58         NFS_CACHEINV(inode);
  59 }
  60 
  61 static void nfs_put_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63 #if 0
  64         clear_inode(inode);
  65 #endif
  66 }
  67 
  68 void nfs_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70         close_fp(sb->u.nfs_sb.s_server.file);
  71         rpc_closesock(sb->u.nfs_sb.s_server.rsock);
  72         lock_super(sb);
  73         sb->s_dev = 0;
  74         unlock_super(sb);
  75         MOD_DEC_USE_COUNT;
  76 }
  77 
  78 /*
  79  * The way this works is that the mount process passes a structure
  80  * in the data argument which contains an open socket to the NFS
  81  * server and the root file handle obtained from the server's mount
  82  * daemon.  We stash theses away in the private superblock fields.
  83  * Later we can add other mount parameters like caching values.
  84  */
  85 
  86 struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
     /* [previous][next][first][last][top][bottom][index][help] */
  87                                    int silent)
  88 {
  89         struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
  90         struct nfs_server *server;
  91         unsigned int fd;
  92         struct file *filp;
  93 
  94         kdev_t dev = sb->s_dev;
  95 
  96         MOD_INC_USE_COUNT;
  97         if (!data) {
  98                 printk("nfs_read_super: missing data argument\n");
  99                 sb->s_dev = 0;
 100                 MOD_DEC_USE_COUNT;
 101                 return NULL;
 102         }
 103         fd = data->fd;
 104         if (data->version != NFS_MOUNT_VERSION) {
 105                 printk("nfs warning: mount version %s than kernel\n",
 106                         data->version < NFS_MOUNT_VERSION ? "older" : "newer");
 107         }
 108         if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {
 109                 printk("nfs_read_super: invalid file descriptor\n");
 110                 sb->s_dev = 0;
 111                 MOD_DEC_USE_COUNT;
 112                 return NULL;
 113         }
 114         if (!S_ISSOCK(filp->f_inode->i_mode)) {
 115                 printk("nfs_read_super: not a socket\n");
 116                 sb->s_dev = 0;
 117                 MOD_DEC_USE_COUNT;
 118                 return NULL;
 119         }
 120         filp->f_count++;
 121         lock_super(sb);
 122 
 123         sb->s_blocksize = 1024; /* XXX */
 124         sb->s_blocksize_bits = 10;
 125         sb->s_magic = NFS_SUPER_MAGIC;
 126         sb->s_dev = dev;
 127         sb->s_op = &nfs_sops;
 128         server = &sb->u.nfs_sb.s_server;
 129         server->file = filp;
 130         server->lock = 0;
 131         server->wait = NULL;
 132         server->flags = data->flags;
 133         server->rsize = data->rsize;
 134         if (server->rsize <= 0)
 135                 server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
 136         else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
 137                 server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
 138         server->wsize = data->wsize;
 139         if (server->wsize <= 0)
 140                 server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
 141         else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
 142                 server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
 143         server->timeo = data->timeo*HZ/10;
 144         server->retrans = data->retrans;
 145         server->acregmin = data->acregmin*HZ;
 146         server->acregmax = data->acregmax*HZ;
 147         server->acdirmin = data->acdirmin*HZ;
 148         server->acdirmax = data->acdirmax*HZ;
 149         strcpy(server->hostname, data->hostname);
 150 
 151         /* Start of JSP NFS patch */
 152         /* Check if passed address in data->addr */
 153         if (data->addr.sin_addr.s_addr == INADDR_ANY) {  /* No address passed */
 154           if (((struct sockaddr_in *)(&server->toaddr))->sin_addr.s_addr == INADDR_ANY) {
 155             printk("NFS: Error passed unconnected socket and no address\n") ;
 156             MOD_DEC_USE_COUNT;
 157             return NULL ;
 158           } else {
 159             /* Need access to socket internals  JSP */
 160             struct socket *sock;
 161             int dummylen ;
 162 
 163          /*   printk("NFS: using socket address\n") ;*/
 164 
 165             sock = &((filp->f_inode)->u.socket_i);
 166 
 167             /* extract the other end of the socket into server->toaddr */
 168             sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
 169           }
 170         } else {
 171         /*  printk("NFS: coppying passed addr to server->toaddr\n") ;*/
 172           memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
 173         }
 174         /* End of JSP NFS patch */
 175 
 176         if ((server->rsock = rpc_makesock(filp)) == NULL) {
 177                 printk("NFS: cannot create RPC socket.\n");
 178                 MOD_DEC_USE_COUNT;
 179                 return NULL;
 180         }
 181 
 182         sb->u.nfs_sb.s_root = data->root;
 183         unlock_super(sb);
 184         if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
 185                 sb->s_dev = 0;
 186                 printk("nfs_read_super: get root inode failed\n");
 187                 MOD_DEC_USE_COUNT;
 188                 return NULL;
 189         }
 190         return sb;
 191 }
 192 
 193 void nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195         int error;
 196         struct nfs_fsinfo res;
 197         struct statfs tmp;
 198 
 199         error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
 200                 &res);
 201         if (error) {
 202                 printk("nfs_statfs: statfs error = %d\n", -error);
 203                 res.bsize = res.blocks = res.bfree = res.bavail = 0;
 204         }
 205         tmp.f_type = NFS_SUPER_MAGIC;
 206         tmp.f_bsize = res.bsize;
 207         tmp.f_blocks = res.blocks;
 208         tmp.f_bfree = res.bfree;
 209         tmp.f_bavail = res.bavail;
 210         tmp.f_files = 0;
 211         tmp.f_ffree = 0;
 212         tmp.f_namelen = NAME_MAX;
 213         memcpy_tofs(buf, &tmp, bufsiz);
 214 }
 215 
 216 /*
 217  * This is our own version of iget that looks up inodes by file handle
 218  * instead of inode number.  We use this technique instead of using
 219  * the vfs read_inode function because there is no way to pass the
 220  * file handle or current attributes into the read_inode function.
 221  * We just have to be careful not to subvert iget's special handling
 222  * of mount points.
 223  */
 224 
 225 struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
     /* [previous][next][first][last][top][bottom][index][help] */
 226                         struct nfs_fattr *fattr)
 227 {
 228         struct nfs_fattr newfattr;
 229         int error;
 230         struct inode *inode;
 231 
 232         if (!sb) {
 233                 printk("nfs_fhget: super block is NULL\n");
 234                 return NULL;
 235         }
 236         if (!fattr) {
 237                 error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
 238                         &newfattr);
 239                 if (error) {
 240                         printk("nfs_fhget: getattr error = %d\n", -error);
 241                         return NULL;
 242                 }
 243                 fattr = &newfattr;
 244         }
 245         if (!(inode = iget(sb, fattr->fileid))) {
 246                 printk("nfs_fhget: iget failed\n");
 247                 return NULL;
 248         }
 249         if (inode->i_dev == sb->s_dev) {
 250                 if (inode->i_ino != fattr->fileid) {
 251                         printk("nfs_fhget: unexpected inode from iget\n");
 252                         return inode;
 253                 }
 254                 *NFS_FH(inode) = *fhandle;
 255                 nfs_refresh_inode(inode, fattr);
 256         }
 257         return inode;
 258 }
 259 
 260 int nfs_notify_change(struct inode *inode, struct iattr *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         struct nfs_sattr sattr;
 263         struct nfs_fattr fattr;
 264         int error;
 265 
 266         sattr.mode = (unsigned) -1;
 267         if (attr->ia_valid & ATTR_MODE) 
 268                 sattr.mode = attr->ia_mode;
 269 
 270         sattr.uid = (unsigned) -1;
 271         if (attr->ia_valid & ATTR_UID)
 272                 sattr.uid = attr->ia_uid;
 273 
 274         sattr.gid = (unsigned) -1;
 275         if (attr->ia_valid & ATTR_GID)
 276                 sattr.gid = attr->ia_gid;
 277 
 278 
 279         sattr.size = (unsigned) -1;
 280         if (attr->ia_valid & ATTR_SIZE)
 281                 sattr.size = S_ISREG(inode->i_mode) ? attr->ia_size : -1;
 282 
 283         sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1;
 284         if (attr->ia_valid & ATTR_MTIME) {
 285                 sattr.mtime.seconds = attr->ia_mtime;
 286                 sattr.mtime.useconds = 0;
 287         }
 288 
 289         sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1;
 290         if (attr->ia_valid & ATTR_ATIME) {
 291                 sattr.atime.seconds = attr->ia_atime;
 292                 sattr.atime.useconds = 0;
 293         }
 294 
 295         error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),
 296                 &sattr, &fattr);
 297         if (!error)
 298                 nfs_refresh_inode(inode, &fattr);
 299         inode->i_dirt = 0;
 300         return error;
 301 }
 302 
 303 /* Every kernel module contains stuff like this. */
 304 
 305 static struct file_system_type nfs_fs_type = {
 306         nfs_read_super, "nfs", 0, NULL
 307 };
 308 
 309 int init_nfs_fs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311         return register_filesystem(&nfs_fs_type);
 312 }
 313 
 314 #ifdef MODULE
 315 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 316 {
 317         int status;
 318 
 319         if ((status = init_nfs_fs()) == 0)
 320                 register_symtab(0);
 321         return status;
 322 }
 323 
 324 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 325 {
 326         unregister_filesystem(&nfs_fs_type);
 327         nfs_kfree_cache();
 328 }
 329 
 330 #endif

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