diff options
Diffstat (limited to 'fs/nfs')
| -rw-r--r-- | fs/nfs/dir.c | 48 | ||||
| -rw-r--r-- | fs/nfs/file.c | 2 | ||||
| -rw-r--r-- | fs/nfs/idmap.c | 2 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 4 | ||||
| -rw-r--r-- | fs/nfs/nfs3proc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4file.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4super.c | 6 | ||||
| -rw-r--r-- | fs/nfs/proc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/super.c | 6 | 
9 files changed, 57 insertions, 17 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1b2d7eb9379..f23f455be42 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -281,7 +281,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des  	for (i = 0; i < array->size; i++) {  		if (array->array[i].cookie == *desc->dir_cookie) { -			struct nfs_inode *nfsi = NFS_I(desc->file->f_path.dentry->d_inode); +			struct nfs_inode *nfsi = NFS_I(file_inode(desc->file));  			struct nfs_open_dir_context *ctx = desc->file->private_data;  			new_pos = desc->current_index + i; @@ -629,7 +629,7 @@ out:  static  int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)  { -	struct inode	*inode = desc->file->f_path.dentry->d_inode; +	struct inode	*inode = file_inode(desc->file);  	int ret;  	ret = nfs_readdir_xdr_to_array(desc, page, inode); @@ -660,7 +660,7 @@ void cache_page_release(nfs_readdir_descriptor_t *desc)  static  struct page *get_cache_page(nfs_readdir_descriptor_t *desc)  { -	return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, +	return read_cache_page(file_inode(desc->file)->i_mapping,  			desc->page_index, (filler_t *)nfs_readdir_filler, desc);  } @@ -764,7 +764,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,  {  	struct page	*page = NULL;  	int		status; -	struct inode *inode = desc->file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(desc->file);  	struct nfs_open_dir_context *ctx = desc->file->private_data;  	dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", @@ -1136,6 +1136,45 @@ out_error:  }  /* + * A weaker form of d_revalidate for revalidating just the dentry->d_inode + * when we don't really care about the dentry name. This is called when a + * pathwalk ends on a dentry that was not found via a normal lookup in the + * parent dir (e.g.: ".", "..", procfs symlinks or mountpoint traversals). + * + * In this situation, we just want to verify that the inode itself is OK + * since the dentry might have changed on the server. + */ +static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags) +{ +	int error; +	struct inode *inode = dentry->d_inode; + +	/* +	 * I believe we can only get a negative dentry here in the case of a +	 * procfs-style symlink. Just assume it's correct for now, but we may +	 * eventually need to do something more here. +	 */ +	if (!inode) { +		dfprintk(LOOKUPCACHE, "%s: %s/%s has negative inode\n", +				__func__, dentry->d_parent->d_name.name, +				dentry->d_name.name); +		return 1; +	} + +	if (is_bad_inode(inode)) { +		dfprintk(LOOKUPCACHE, "%s: %s/%s has dud inode\n", +				__func__, dentry->d_parent->d_name.name, +				dentry->d_name.name); +		return 0; +	} + +	error = nfs_revalidate_inode(NFS_SERVER(inode), inode); +	dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n", +			__func__, inode->i_ino, error ? "invalid" : "valid"); +	return !error; +} + +/*   * This is called from dput() when d_count is going to 0.   */  static int nfs_dentry_delete(const struct dentry *dentry) @@ -1202,6 +1241,7 @@ static void nfs_d_release(struct dentry *dentry)  const struct dentry_operations nfs_dentry_operations = {  	.d_revalidate	= nfs_lookup_revalidate, +	.d_weak_revalidate	= nfs_weak_revalidate,  	.d_delete	= nfs_dentry_delete,  	.d_iput		= nfs_dentry_iput,  	.d_automount	= nfs_d_automount, diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 3c2b893665b..29f4a48a0ee 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -292,7 +292,7 @@ static int  nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)  {  	int ret; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	do {  		ret = filemap_write_and_wait_range(inode->i_mapping, start, end); diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b9623d19d59..dc0f98dfa71 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -765,7 +765,7 @@ out:  static ssize_t  idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)  { -	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); +	struct rpc_inode *rpci = RPC_I(file_inode(filp));  	struct idmap *idmap = (struct idmap *)rpci->private;  	struct key_construction *cons;  	struct idmap_msg im; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 468ba8bf0f5..b586fe9af47 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -711,7 +711,7 @@ EXPORT_SYMBOL_GPL(put_nfs_open_context);   */  void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)  { -	struct inode *inode = filp->f_path.dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct nfs_inode *nfsi = NFS_I(inode);  	filp->private_data = get_nfs_open_context(ctx); @@ -744,7 +744,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c  static void nfs_file_clear_open_context(struct file *filp)  { -	struct inode *inode = filp->f_path.dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct nfs_open_context *ctx = nfs_file_open_context(filp);  	if (ctx) { diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 70efb63b1e4..43ea96ced28 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -872,7 +872,7 @@ static void nfs3_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess  static int  nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)  { -	struct inode *inode = filp->f_path.dentry->d_inode; +	struct inode *inode = file_inode(filp);  	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);  } diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 08ddcccb888..13e6bb3e3fe 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -94,7 +94,7 @@ static int  nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)  {  	int ret; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	do {  		ret = filemap_write_and_wait_range(inode->i_mapping, start, end); diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 84d2e9e2f31..569b166cc05 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -28,7 +28,7 @@ static struct file_system_type nfs4_remote_fs_type = {  	.name		= "nfs4",  	.mount		= nfs4_remote_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  static struct file_system_type nfs4_remote_referral_fs_type = { @@ -36,7 +36,7 @@ static struct file_system_type nfs4_remote_referral_fs_type = {  	.name		= "nfs4",  	.mount		= nfs4_remote_referral_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  struct file_system_type nfs4_referral_fs_type = { @@ -44,7 +44,7 @@ struct file_system_type nfs4_referral_fs_type = {  	.name		= "nfs4",  	.mount		= nfs4_referral_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  static const struct super_operations nfs4_sops = { diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index f084dac948e..fc8de9016ac 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -662,7 +662,7 @@ nfs_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)  static int  nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)  { -	struct inode *inode = filp->f_path.dentry->d_inode; +	struct inode *inode = file_inode(filp);  	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);  } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index befbae0cce4..a9dc5fc2995 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -291,7 +291,7 @@ struct file_system_type nfs_fs_type = {  	.name		= "nfs",  	.mount		= nfs_fs_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  EXPORT_SYMBOL_GPL(nfs_fs_type); @@ -300,7 +300,7 @@ struct file_system_type nfs_xdev_fs_type = {  	.name		= "nfs",  	.mount		= nfs_xdev_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  const struct super_operations nfs_sops = { @@ -330,7 +330,7 @@ struct file_system_type nfs4_fs_type = {  	.name		= "nfs4",  	.mount		= nfs_fs_mount,  	.kill_sb	= nfs_kill_super, -	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,  };  EXPORT_SYMBOL_GPL(nfs4_fs_type);  |