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;
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;
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;
}
/*
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;
}
out:
return inode;
-/*
+/* FIXME
fail_dlim:
make_bad_inode(inode);
iput(inode);
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;
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;
/* 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;
}
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);
|| 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)
#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));
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;
*/
nfs_invalidate_inode(inode);
out_err:
- return -EIO;
+ NFS_FLAGS(inode) |= NFS_INO_STALE;
+ return -ESTALE;
}
/*
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))
rpciod_down(); /* release rpciod */
- destroy_nfsv4_state(server);
-
if (server->hostname != NULL)
kfree(server->hostname);
kfree(server);
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;
}
}
+ sb->s_time_gran = 1;
+
sb->s_op = &nfs4_sops;
err = nfs_sb_init(sb, authflavour);
if (err == 0)
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 = {
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;
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
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:
static void __exit exit_nfs_fs(void)
{
+#ifdef CONFIG_NFS_DIRECTIO
+ nfs_destroy_directcache();
+#endif
nfs_destroy_writepagecache();
nfs_destroy_readpagecache();
nfs_destroy_inodecache();