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

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