]> err.no Git - linux-2.6/blobdiff - fs/nfs/inode.c
[PATCH] tightening hugetlb strict accounting
[linux-2.6] / fs / nfs / inode.c
index 17654bffc3c6e6a228b1be111cd410b798ccb566..937fbfc381bbd4746ddf55367df2d920d44dc0fe 100644 (file)
@@ -65,7 +65,7 @@ static int nfs_write_inode(struct inode *,int);
 static void nfs_delete_inode(struct inode *);
 static void nfs_clear_inode(struct inode *);
 static void nfs_umount_begin(struct super_block *);
-static int  nfs_statfs(struct super_block *, struct kstatfs *);
+static int  nfs_statfs(struct dentry *, struct kstatfs *);
 static int  nfs_show_options(struct seq_file *, struct vfsmount *);
 static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
 static void nfs_zap_acl_cache(struct inode *);
@@ -107,7 +107,7 @@ static struct rpc_version * nfs_version[] = {
 static struct rpc_program      nfs_program = {
        .name                   = "nfs",
        .number                 = NFS_PROGRAM,
-       .nrvers                 = sizeof(nfs_version) / sizeof(nfs_version[0]),
+       .nrvers                 = ARRAY_SIZE(nfs_version),
        .version                = nfs_version,
        .stats                  = &nfs_rpcstat,
        .pipe_dir_name          = "/nfs",
@@ -122,7 +122,7 @@ static struct rpc_version * nfsacl_version[] = {
 struct rpc_program             nfsacl_program = {
        .name =                 "nfsacl",
        .number =               NFS_ACL_PROGRAM,
-       .nrvers =               sizeof(nfsacl_version) / sizeof(nfsacl_version[0]),
+       .nrvers =               ARRAY_SIZE(nfsacl_version),
        .version =              nfsacl_version,
        .stats =                &nfsacl_rpcstat,
 };
@@ -137,7 +137,7 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
 static int
 nfs_write_inode(struct inode *inode, int sync)
 {
-       int flags = sync ? FLUSH_WAIT : 0;
+       int flags = sync ? FLUSH_SYNC : 0;
        int ret;
 
        ret = nfs_commit_inode(inode, flags);
@@ -241,7 +241,6 @@ static struct inode *
 nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
 {
        struct nfs_server       *server = NFS_SB(sb);
-       struct inode *rooti;
        int                     error;
 
        error = server->rpc_ops->getroot(server, rootfh, fsinfo);
@@ -250,10 +249,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f
                return ERR_PTR(error);
        }
 
-       rooti = nfs_fhget(sb, rootfh, fsinfo->fattr);
-       if (!rooti)
-               return ERR_PTR(-ENOMEM);
-       return rooti;
+       return nfs_fhget(sb, rootfh, fsinfo->fattr);
 }
 
 /*
@@ -538,8 +534,9 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
 }
 
 static int
-nfs_statfs(struct super_block *sb, struct kstatfs *buf)
+nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
+       struct super_block *sb = dentry->d_sb;
        struct nfs_server *server = NFS_SB(sb);
        unsigned char blockbits;
        unsigned long blockres;
@@ -704,12 +701,9 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
        /*
         * Display superblock I/O counters
         */
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+       for_each_possible_cpu(cpu) {
                struct nfs_iostats *stats;
 
-               if (!cpu_possible(cpu))
-                       continue;
-
                preempt_disable();
                stats = per_cpu_ptr(nfss->io_stats, cpu);
 
@@ -853,7 +847,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                .fh     = fh,
                .fattr  = fattr
        };
-       struct inode *inode = NULL;
+       struct inode *inode = ERR_PTR(-ENOENT);
        unsigned long hash;
 
        if ((fattr->valid & NFS_ATTR_FATTR) == 0)
@@ -866,8 +860,11 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
 
        hash = nfs_fattr_to_ino_t(fattr);
 
-       if (!(inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc)))
+       inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
+       if (inode == NULL) {
+               inode = ERR_PTR(-ENOMEM);
                goto out_no_inode;
+       }
 
        if (inode->i_state & I_NEW) {
                struct nfs_inode *nfsi = NFS_I(inode);
@@ -936,7 +933,7 @@ out:
        return inode;
 
 out_no_inode:
-       printk("nfs_fhget: iget failed\n");
+       dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
        goto out;
 }
 
@@ -1052,7 +1049,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        int err;
 
        /* Flush out writes to the server in order to update c/mtime */
-       nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
+       nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT);
 
        /*
         * We may force a getattr if the user cares about atime.
@@ -1694,8 +1691,8 @@ static int nfs_compare_super(struct super_block *sb, void *data)
        return !nfs_compare_fh(&old->fh, &server->fh);
 }
 
-static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data)
+static int nfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
        int error;
        struct nfs_server *server = NULL;
@@ -1703,14 +1700,14 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
        struct nfs_fh *root;
        struct nfs_mount_data *data = raw_data;
 
-       s = ERR_PTR(-EINVAL);
+       error = -EINVAL;
        if (data == NULL) {
                dprintk("%s: missing data argument\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
        if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
                dprintk("%s: bad mount version\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
        switch (data->version) {
                case 1:
@@ -1722,7 +1719,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
                                dprintk("%s: mount structure version %d does not support NFSv3\n",
                                                __FUNCTION__,
                                                data->version);
-                               goto out_err;
+                               goto out_err_noserver;
                        }
                        data->root.size = NFS2_FHSIZE;
                        memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
@@ -1731,24 +1728,24 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
                                dprintk("%s: mount structure version %d does not support strong security\n",
                                                __FUNCTION__,
                                                data->version);
-                               goto out_err;
+                               goto out_err_noserver;
                        }
                case 5:
                        memset(data->context, 0, sizeof(data->context));
        }
 #ifndef CONFIG_NFS_V3
        /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
-       s = ERR_PTR(-EPROTONOSUPPORT);
+       error = -EPROTONOSUPPORT;
        if (data->flags & NFS_MOUNT_VER3) {
                dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
 #endif /* CONFIG_NFS_V3 */
 
-       s = ERR_PTR(-ENOMEM);
+       error = -ENOMEM;
        server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
        if (!server)
-               goto out_err;
+               goto out_err_noserver;
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -1758,7 +1755,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
                root->size = data->root.size;
        else
                root->size = NFS2_FHSIZE;
-       s = ERR_PTR(-EINVAL);
+       error = -EINVAL;
        if (root->size > sizeof(root->data)) {
                dprintk("%s: invalid root filehandle\n", __FUNCTION__);
                goto out_err;
@@ -1774,32 +1771,44 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
        }
 
        /* Fire up rpciod if not yet running */
-       s = ERR_PTR(rpciod_up());
-       if (IS_ERR(s)) {
-               dprintk("%s: couldn't start rpciod! Error = %ld\n",
-                               __FUNCTION__, PTR_ERR(s));
+       error = rpciod_up();
+       if (error < 0) {
+               dprintk("%s: couldn't start rpciod! Error = %d\n",
+                               __FUNCTION__, error);
                goto out_err;
        }
 
        s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
-       if (IS_ERR(s) || s->s_root)
+       if (IS_ERR(s)) {
+               error = PTR_ERR(s);
+               goto out_err_rpciod;
+       }
+
+       if (s->s_root)
                goto out_rpciod_down;
 
        s->s_flags = flags;
 
-       error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+       error = nfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
        if (error) {
                up_write(&s->s_umount);
                deactivate_super(s);
-               return ERR_PTR(error);
+               return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
+
 out_rpciod_down:
        rpciod_down();
+       kfree(server);
+       return simple_set_mnt(mnt, s);
+
+out_err_rpciod:
+       rpciod_down();
 out_err:
        kfree(server);
-       return s;
+out_err_noserver:
+       return error;
 }
 
 static void nfs_kill_super(struct super_block *s)
@@ -2036,8 +2045,8 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
        return dst;
 }
 
-static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data)
+static int nfs4_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
        int error;
        struct nfs_server *server;
@@ -2047,16 +2056,16 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
 
        if (data == NULL) {
                dprintk("%s: missing data argument\n", __FUNCTION__);
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
        if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
                dprintk("%s: bad mount version\n", __FUNCTION__);
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
        server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
        if (!server)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -2078,51 +2087,59 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
 
        /* We now require that the mount process passes the remote address */
        if (data->host_addrlen != sizeof(server->addr)) {
-               s = ERR_PTR(-EINVAL);
+               error = -EINVAL;
                goto out_free;
        }
        if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
-               s = ERR_PTR(-EFAULT);
+               error = -EFAULT;
                goto out_free;
        }
        if (server->addr.sin_family != AF_INET ||
            server->addr.sin_addr.s_addr == INADDR_ANY) {
                dprintk("%s: mount program didn't pass remote IP address!\n",
                                __FUNCTION__);
-               s = ERR_PTR(-EINVAL);
+               error = -EINVAL;
                goto out_free;
        }
 
        /* Fire up rpciod if not yet running */
-       s = ERR_PTR(rpciod_up());
-       if (IS_ERR(s)) {
-               dprintk("%s: couldn't start rpciod! Error = %ld\n",
-                               __FUNCTION__, PTR_ERR(s));
+       error = rpciod_up();
+       if (error < 0) {
+               dprintk("%s: couldn't start rpciod! Error = %d\n",
+                               __FUNCTION__, error);
                goto out_free;
        }
 
        s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
-
-       if (IS_ERR(s) || s->s_root)
+       if (IS_ERR(s)) {
+               error = PTR_ERR(s);
                goto out_free;
+       }
+
+       if (s->s_root) {
+               kfree(server->mnt_path);
+               kfree(server->hostname);
+               kfree(server);
+               return simple_set_mnt(mnt, s);
+       }
 
        s->s_flags = flags;
 
-       error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+       error = nfs4_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
        if (error) {
                up_write(&s->s_umount);
                deactivate_super(s);
-               return ERR_PTR(error);
+               return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
 out_err:
-       s = (struct super_block *)p;
+       error = PTR_ERR(p);
 out_free:
        kfree(server->mnt_path);
        kfree(server->hostname);
        kfree(server);
-       return s;
+       return error;
 }
 
 static void nfs4_kill_super(struct super_block *sb)
@@ -2277,7 +2294,8 @@ static int nfs_init_inodecache(void)
 {
        nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
                                             sizeof(struct nfs_inode),
-                                            0, SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (nfs_inode_cachep == NULL)
                return -ENOMEM;