X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fnfs%2Finode.c;h=31166a8c650c177e08f64b754aac7e690f3039dc;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=60b30747801240cc624dd555e717971908577911;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 60b307478..31166a8c6 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -462,6 +462,7 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) if (server->flags & NFS_MOUNT_VER3) { if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) server->namelen = NFS3_MAXNAMLEN; + sb->s_time_gran = 1; } else { if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) server->namelen = NFS2_MAXNAMLEN; @@ -491,13 +492,27 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf) if (error < 0) goto out_err; - buf->f_frsize = server->wtmult; + /* + * Current versions of glibc do not correctly handle the + * case where f_frsize != f_bsize. Eventually we want to + * report the value of wtmult in this field. + */ + buf->f_frsize = sb->s_blocksize; + + /* + * On most *nix systems, f_blocks, f_bfree, and f_bavail + * are reported in units of f_frsize. Linux hasn't had + * an f_frsize field in its statfs struct until recently, + * thus historically Linux's sys_statfs reports these + * fields in units of f_bsize. + */ buf->f_bsize = sb->s_blocksize; blockbits = sb->s_blocksize_bits; blockres = (1 << blockbits) - 1; buf->f_blocks = (res.tbytes + blockres) >> blockbits; buf->f_bfree = (res.fbytes + blockres) >> blockbits; buf->f_bavail = (res.abytes + blockres) >> blockbits; + buf->f_files = res.tfiles; buf->f_ffree = res.afiles; @@ -571,9 +586,9 @@ nfs_zap_caches(struct inode *inode) memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) - nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; else - nfsi->flags |= NFS_INO_INVALID_ATTR; + nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; } /* @@ -611,7 +626,7 @@ nfs_find_actor(struct inode *inode, void *opaque) return 0; if (nfs_compare_fh(NFS_FH(inode), fh)) return 0; - if (is_bad_inode(inode)) + if (is_bad_inode(inode) || NFS_STALE(inode)) return 0; return 1; } @@ -723,7 +738,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) out: return inode; -/* +/* FIXME fail_dlim: make_bad_inode(inode); iput(inode); @@ -781,13 +796,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) vmtruncate(inode, attr->ia_size); } } - if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { - struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; - if (*cred) { - put_rpccred(*cred); - *cred = NULL; - } - } + if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) + NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; nfs_end_data_update(inode); unlock_kernel(); return error; @@ -964,14 +974,14 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) lock_kernel(); if (!inode || is_bad_inode(inode)) goto out_nowait; - if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode) + if (NFS_STALE(inode)) goto out_nowait; while (NFS_REVALIDATING(inode)) { status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING); if (status < 0) goto out_nowait; - if (NFS_SERVER(inode)->flags & NFS_MOUNT_NOAC) + if (NFS_ATTRTIMEO(inode) == 0) continue; if (NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) continue; @@ -983,14 +993,14 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) /* Protect against RPC races by saving the change attribute */ verifier = nfs_save_change_attribute(inode); status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); - if (status) { + if (status != 0) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", inode->i_sb->s_id, (long long)NFS_FILEID(inode), status); if (status == -ESTALE) { - NFS_FLAGS(inode) |= NFS_INO_STALE; - if (inode != inode->i_sb->s_root->d_inode) - remove_inode_hash(inode); + nfs_zap_caches(inode); + if (!S_ISDIR(inode->i_mode)) + NFS_FLAGS(inode) |= NFS_INO_STALE; } goto out; } @@ -1029,7 +1039,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) inode->i_sb->s_id, (long long)NFS_FILEID(inode)); - NFS_FLAGS(inode) &= ~NFS_INO_STALE; out: NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; wake_up(&nfsi->nfs_i_wait); @@ -1184,7 +1193,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) || inode->i_uid != uid || inode->i_gid != gid || inode->i_xid != xid) - nfsi->flags |= NFS_INO_INVALID_ATTR; + nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; /* Has the link count changed? */ if (inode->i_nlink != fattr->nlink) @@ -1296,7 +1305,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign #endif nfsi->change_attr = fattr->change_attr; if (!data_unstable) - invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; } memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); @@ -1309,14 +1318,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || inode->i_uid != uid || inode->i_gid != gid || - inode->i_xid != xid) { - struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; - if (*cred) { - put_rpccred(*cred); - *cred = NULL; - } - invalid |= NFS_INO_INVALID_ATTR; - } + inode->i_xid != xid) + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; @@ -1367,7 +1370,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign */ nfs_invalidate_inode(inode); out_err: - return -EIO; + NFS_FLAGS(inode) |= NFS_INO_STALE; + return -ESTALE; } /* @@ -1481,8 +1485,6 @@ static void nfs_kill_super(struct super_block *s) kill_anon_super(s); - nfs4_renewd_prepare_shutdown(server); - if (server->client != NULL && !IS_ERR(server->client)) rpc_shutdown_client(server->client); if (server->client_sys != NULL && !IS_ERR(server->client_sys)) @@ -1493,8 +1495,6 @@ static void nfs_kill_super(struct super_block *s) rpciod_down(); /* release rpciod */ - destroy_nfsv4_state(server); - if (server->hostname != NULL) kfree(server->hostname); kfree(server); @@ -1575,9 +1575,6 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, server->wsize = nfs_block_size(data->wsize, NULL); server->flags = data->flags & NFS_MOUNT_FLAGMASK; - /* NFSv4 doesn't use NLM locking */ - server->flags |= NFS_MOUNT_NONLM; - server->acregmin = data->acregmin*HZ; server->acregmax = data->acregmax*HZ; server->acdirmin = data->acdirmin*HZ; @@ -1685,6 +1682,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, } } + sb->s_time_gran = 1; + sb->s_op = &nfs4_sops; err = nfs_sb_init(sb, authflavour); if (err == 0) @@ -1822,8 +1821,22 @@ out_free: static void nfs4_kill_super(struct super_block *sb) { + struct nfs_server *server = NFS_SB(sb); + nfs_return_all_delegations(sb); - nfs_kill_super(sb); + kill_anon_super(sb); + + nfs4_renewd_prepare_shutdown(server); + + if (server->client != NULL && !IS_ERR(server->client)) + rpc_shutdown_client(server->client); + rpciod_down(); /* release rpciod */ + + destroy_nfsv4_state(server); + + if (server->hostname != NULL) + kfree(server->hostname); + kfree(server); } static struct file_system_type nfs4_fs_type = { @@ -1853,9 +1866,13 @@ static struct file_system_type nfs4_fs_type = { extern int nfs_init_nfspagecache(void); extern void nfs_destroy_nfspagecache(void); extern int nfs_init_readpagecache(void); -extern int nfs_destroy_readpagecache(void); +extern void nfs_destroy_readpagecache(void); extern int nfs_init_writepagecache(void); -extern int nfs_destroy_writepagecache(void); +extern void nfs_destroy_writepagecache(void); +#ifdef CONFIG_NFS_DIRECTIO +extern int nfs_init_directcache(void); +extern void nfs_destroy_directcache(void); +#endif static kmem_cache_t * nfs_inode_cachep; @@ -1936,6 +1953,12 @@ static int __init init_nfs_fs(void) if (err) goto out1; +#ifdef CONFIG_NFS_DIRECTIO + err = nfs_init_directcache(); + if (err) + goto out0; +#endif + #ifdef CONFIG_PROC_FS rpc_proc_register(&nfs_rpcstat); #endif @@ -1946,8 +1969,14 @@ static int __init init_nfs_fs(void) goto out; return 0; out: +#ifdef CONFIG_PROC_FS rpc_proc_unregister("nfs"); +#endif nfs_destroy_writepagecache(); +#ifdef CONFIG_NFS_DIRECTIO +out0: + nfs_destroy_directcache(); +#endif out1: nfs_destroy_readpagecache(); out2: @@ -1960,6 +1989,9 @@ out4: static void __exit exit_nfs_fs(void) { +#ifdef CONFIG_NFS_DIRECTIO + nfs_destroy_directcache(); +#endif nfs_destroy_writepagecache(); nfs_destroy_readpagecache(); nfs_destroy_inodecache();