#include <asm/uaccess.h>
#include "nfs4_fs.h"
+#include "callback.h"
#include "delegation.h"
#define NFSDBG_FACILITY NFSDBG_VFS
clnt->cl_intr = 1;
clnt->cl_softrtry = 1;
- clnt->cl_chatty = 1;
return clnt;
if (mapping->nrpages == 0)
return 0;
unmap_mapping_range(mapping, 0, 0, 0);
- ret = filemap_fdatawrite(mapping);
- if (ret != 0)
- goto out;
- ret = filemap_fdatawait(mapping);
+ ret = filemap_write_and_wait(mapping);
if (ret != 0)
goto out;
ret = nfs_wb_all(mapping->host);
nfs_begin_data_update(inode);
/* Write all dirty data if we're changing file permissions or size */
if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) {
- if (filemap_fdatawrite(inode->i_mapping) == 0)
- filemap_fdatawait(inode->i_mapping);
+ filemap_write_and_wait(inode->i_mapping);
nfs_wb_all(inode);
}
/*
/* Flush out writes to the server in order to update c/mtime */
nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
- if (__IS_FLG(inode, MS_NOATIME))
- need_atime = 0;
- else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
+
+ /*
+ * We may force a getattr if the user cares about atime.
+ *
+ * Note that we only have to check the vfsmount flags here:
+ * - NFS always sets S_NOATIME by so checking it would give a
+ * bogus result
+ * - NFS never sets MS_NOATIME or MS_NODIRATIME so there is
+ * no point in checking those.
+ */
+ if ((mnt->mnt_flags & MNT_NOATIME) ||
+ ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
need_atime = 0;
- /* We may force a getattr if the user cares about atime */
+
if (need_atime)
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
else
atomic_dec(&nfsi->data_updates);
}
+static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
+ && nfsi->change_attr == fattr->pre_change_attr) {
+ nfsi->change_attr = fattr->change_attr;
+ nfsi->cache_change_attribute = jiffies;
+ }
+
+ /* If we have atomic WCC data, we may update some attributes */
+ if ((fattr->valid & NFS_ATTR_WCC) != 0) {
+ if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
+ memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+ nfsi->cache_change_attribute = jiffies;
+ }
+ if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
+ memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
+ nfsi->cache_change_attribute = jiffies;
+ }
+ if (inode->i_size == fattr->pre_size && nfsi->npages == 0) {
+ inode->i_size = fattr->size;
+ nfsi->cache_change_attribute = jiffies;
+ }
+ }
+}
+
/**
* nfs_check_inode_attributes - verify consistency of the inode attribute cache
* @inode - pointer to inode
int data_unstable;
+ if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+ return 0;
+
/* Are we in the process of updating data on the server? */
data_unstable = nfs_caches_unstable(inode);
- if (fattr->valid & NFS_ATTR_FATTR_V4) {
- if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
- && nfsi->change_attr == fattr->pre_change_attr)
- nfsi->change_attr = fattr->change_attr;
- if (nfsi->change_attr != fattr->change_attr) {
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
- if (!data_unstable)
- nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
- }
- }
+ /* Do atomic weak cache consistency updates */
+ nfs_wcc_update_inode(inode, fattr);
- if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
- return 0;
+ if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
+ nfsi->change_attr != fattr->change_attr) {
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+ if (!data_unstable)
+ nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
}
/* Has the inode gone and changed behind our back? */
cur_size = i_size_read(inode);
new_isize = nfs_size_to_loff_t(fattr->size);
- /* If we have atomic WCC data, we may update some attributes */
- if ((fattr->valid & NFS_ATTR_WCC) != 0) {
- if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime))
- memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
- if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime))
- memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
- }
-
/* Verify a few of the more important attributes */
if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
if (data_stable)
nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+ /* Do atomic weak cache consistency updates */
+ nfs_wcc_update_inode(inode, fattr);
+
/* Check if our cached file size is stale */
new_isize = nfs_size_to_loff_t(fattr->size);
cur_isize = i_size_read(inode);
}
clnt->cl_intr = 1;
clnt->cl_softrtry = 1;
- clnt->cl_chatty = 1;
clp->cl_rpcclient = clnt;
memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
nfs_idmap_new(clp);
.fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
};
+static const int nfs_set_port_min = 0;
+static const int nfs_set_port_max = 65535;
+static int param_set_port(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ int num = simple_strtol(val, &endp, 0);
+ if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
+ return -EINVAL;
+ *((int *)kp->arg) = num;
+ return 0;
+}
+
+module_param_call(callback_tcpport, param_set_port, param_get_int,
+ &nfs_callback_set_tcpport, 0644);
+
+static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ int num = simple_strtol(val, &endp, 0);
+ int jif = num * HZ;
+ if (endp == val || *endp || num < 0 || jif < num)
+ return -EINVAL;
+ *((int *)kp->arg) = jif;
+ return 0;
+}
+
+module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
+ &nfs_idmap_cache_timeout, 0644);
+
#define nfs4_init_once(nfsi) \
do { \
INIT_LIST_HEAD(&(nfsi)->open_states); \
nfsi->delegation_state = 0; \
init_rwsem(&nfsi->rwsem); \
} while(0)
-#define register_nfs4fs() register_filesystem(&nfs4_fs_type)
-#define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type)
+
+static inline int register_nfs4fs(void)
+{
+ int ret;
+
+ ret = nfs_register_sysctl();
+ if (ret != 0)
+ return ret;
+ ret = register_filesystem(&nfs4_fs_type);
+ if (ret != 0)
+ nfs_unregister_sysctl();
+ return ret;
+}
+
+static inline void unregister_nfs4fs(void)
+{
+ unregister_filesystem(&nfs4_fs_type);
+ nfs_unregister_sysctl();
+}
#else
#define nfs4_init_once(nfsi) \
do { } while (0)