Newer
Older
/*
* linux/fs/nfs/inode.c
*
* Copyright (C) 1992 Rick Sladkey
*
* nfs inode and superblock handling functions
*
* Modularised by Alan Cox <alan@lxorguk.ukuu.org.uk>, while hacking some
* experimental NFS changes. Modularisation taken straight from SYS5 fs.
*
* Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
* J.S.Peatfield@damtp.cam.ac.uk
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/metrics.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/nfs_xdr.h>
#include <linux/slab.h>

Frank Filz
committed
#include <linux/compat.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "callback.h"
#include "iostat.h"
#include "fscache.h"
#include "dns_resolve.h"
#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1
/* Default is to see 64-bit inode numbers */
static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
static struct kmem_cache * nfs_inode_cachep;
static inline unsigned long
nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
{
return nfs_fileid_to_ino_t(fattr->fileid);
}
/**
* nfs_wait_bit_killable - helper for functions that are sleeping on bit locks
* @word: long word containing the bit lock
*/
int nfs_wait_bit_killable(void *word)
{
if (fatal_signal_pending(current))
return -ERESTARTSYS;
schedule();
return 0;
}
/**
* nfs_compat_user_ino64 - returns the user-visible inode number
* @fileid: 64-bit fileid
*
* This function returns a 32-bit inode number if the boot parameter
* nfs.enable_ino64 is zero.
*/
u64 nfs_compat_user_ino64(u64 fileid)
{

Frank Filz
committed
#ifdef CONFIG_COMPAT
compat_ulong_t ino;
#else
unsigned long ino;
#endif
if (enable_ino64)
return fileid;
ino = fileid;
if (sizeof(ino) < sizeof(fileid))
ino ^= fileid >> (sizeof(fileid)-sizeof(ino)) * 8;
return ino;
}
static void nfs_clear_inode(struct inode *inode)
/*
* The following should never happen...
*/
BUG_ON(nfs_have_writebacks(inode));
BUG_ON(!list_empty(&NFS_I(inode)->open_files));

Trond Myklebust
committed
nfs_zap_acl_cache(inode);
nfs_access_zap_cache(inode);
nfs_fscache_release_inode_cookie(inode);
void nfs_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
end_writeback(inode);
nfs_clear_inode(inode);
}
/**
* nfs_sync_mapping - helper to flush all mmapped dirty data to disk
*/
int nfs_sync_mapping(struct address_space *mapping)
{
if (mapping->nrpages != 0) {
unmap_mapping_range(mapping, 0, 0, 0);
ret = nfs_wb_all(mapping->host);
}
static void nfs_zap_caches_locked(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
int mode = inode->i_mode;
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = jiffies;
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
void nfs_zap_caches(struct inode *inode)
{
spin_lock(&inode->i_lock);
nfs_zap_caches_locked(inode);
spin_unlock(&inode->i_lock);

Trond Myklebust
committed
}
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
{
if (mapping->nrpages != 0) {
spin_lock(&inode->i_lock);
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
spin_unlock(&inode->i_lock);
}
}
void nfs_zap_acl_cache(struct inode *inode)

Trond Myklebust
committed
{
void (*clear_acl_cache)(struct inode *);
clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
if (clear_acl_cache != NULL)
clear_acl_cache(inode);
spin_lock(&inode->i_lock);
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
spin_unlock(&inode->i_lock);
void nfs_invalidate_atime(struct inode *inode)
{
spin_lock(&inode->i_lock);
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
spin_unlock(&inode->i_lock);
}
* Invalidate, but do not unhash, the inode.
* NB: must be called with inode->i_lock held!
static void nfs_invalidate_inode(struct inode *inode)
Loading
Loading full blame...