| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | /* AFS caching stuff
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  * Written by David Howells (dhowells@redhat.com) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version | 
					
						
							|  |  |  |  * 2 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | #include <linux/sched.h>
 | 
					
						
							|  |  |  | #include "internal.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				       void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				       void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data, | 
					
						
							|  |  |  | 						      const void *buffer, | 
					
						
							|  |  |  | 						      uint16_t buflen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					    void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					    void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static enum fscache_checkaux afs_vlocation_cache_check_aux( | 
					
						
							|  |  |  | 	void *cookie_netfs_data, const void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					 void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static void afs_vnode_cache_get_attr(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				     uint64_t *size); | 
					
						
							|  |  |  | static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					void *buffer, uint16_t buflen); | 
					
						
							|  |  |  | static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, | 
					
						
							|  |  |  | 						       const void *buffer, | 
					
						
							|  |  |  | 						       uint16_t buflen); | 
					
						
							|  |  |  | static void afs_vnode_cache_now_uncached(void *cookie_netfs_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct fscache_netfs afs_cache_netfs = { | 
					
						
							|  |  |  | 	.name			= "afs", | 
					
						
							|  |  |  | 	.version		= 0, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct fscache_cookie_def afs_cell_cache_index_def = { | 
					
						
							|  |  |  | 	.name		= "AFS.cell", | 
					
						
							|  |  |  | 	.type		= FSCACHE_COOKIE_TYPE_INDEX, | 
					
						
							|  |  |  | 	.get_key	= afs_cell_cache_get_key, | 
					
						
							|  |  |  | 	.get_aux	= afs_cell_cache_get_aux, | 
					
						
							|  |  |  | 	.check_aux	= afs_cell_cache_check_aux, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct fscache_cookie_def afs_vlocation_cache_index_def = { | 
					
						
							|  |  |  | 	.name			= "AFS.vldb", | 
					
						
							|  |  |  | 	.type			= FSCACHE_COOKIE_TYPE_INDEX, | 
					
						
							|  |  |  | 	.get_key		= afs_vlocation_cache_get_key, | 
					
						
							|  |  |  | 	.get_aux		= afs_vlocation_cache_get_aux, | 
					
						
							|  |  |  | 	.check_aux		= afs_vlocation_cache_check_aux, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct fscache_cookie_def afs_volume_cache_index_def = { | 
					
						
							|  |  |  | 	.name		= "AFS.volume", | 
					
						
							|  |  |  | 	.type		= FSCACHE_COOKIE_TYPE_INDEX, | 
					
						
							|  |  |  | 	.get_key	= afs_volume_cache_get_key, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct fscache_cookie_def afs_vnode_cache_index_def = { | 
					
						
							|  |  |  | 	.name			= "AFS.vnode", | 
					
						
							|  |  |  | 	.type			= FSCACHE_COOKIE_TYPE_DATAFILE, | 
					
						
							|  |  |  | 	.get_key		= afs_vnode_cache_get_key, | 
					
						
							|  |  |  | 	.get_attr		= afs_vnode_cache_get_attr, | 
					
						
							|  |  |  | 	.get_aux		= afs_vnode_cache_get_aux, | 
					
						
							|  |  |  | 	.check_aux		= afs_vnode_cache_check_aux, | 
					
						
							|  |  |  | 	.now_uncached		= afs_vnode_cache_now_uncached, | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * set the key for the index entry | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				       void *buffer, uint16_t bufmax) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_cell *cell = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t klen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_enter("%p,%p,%u", cell, buffer, bufmax); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	klen = strlen(cell->name); | 
					
						
							|  |  |  | 	if (klen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	memcpy(buffer, cell->name, klen); | 
					
						
							|  |  |  | 	return klen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * provide new auxiliary cache data | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				       void *buffer, uint16_t bufmax) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_cell *cell = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t dlen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_enter("%p,%p,%u", cell, buffer, bufmax); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	dlen = cell->vl_naddrs * sizeof(cell->vl_addrs[0]); | 
					
						
							|  |  |  | 	dlen = min(dlen, bufmax); | 
					
						
							|  |  |  | 	dlen &= ~(sizeof(cell->vl_addrs[0]) - 1); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	memcpy(buffer, cell->vl_addrs, dlen); | 
					
						
							|  |  |  | 	return dlen; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * check that the auxiliary data indicates that the entry is still valid | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data, | 
					
						
							|  |  |  | 						      const void *buffer, | 
					
						
							|  |  |  | 						      uint16_t buflen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	_leave(" = OKAY"); | 
					
						
							|  |  |  | 	return FSCACHE_CHECKAUX_OKAY; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * set the key for the index entry | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					    void *buffer, uint16_t bufmax) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_vlocation *vlocation = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t klen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name)); | 
					
						
							|  |  |  | 	if (klen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	memcpy(buffer, vlocation->vldb.name, klen); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_leave(" = %u", klen); | 
					
						
							|  |  |  | 	return klen; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * provide new auxiliary cache data | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					    void *buffer, uint16_t bufmax) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct afs_vlocation *vlocation = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t dlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dlen = sizeof(struct afs_cache_vlocation); | 
					
						
							|  |  |  | 	dlen -= offsetof(struct afs_cache_vlocation, nservers); | 
					
						
							|  |  |  | 	if (dlen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_leave(" = %u", dlen); | 
					
						
							|  |  |  | 	return dlen; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * check that the auxiliary data indicates that the entry is still valid | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | enum fscache_checkaux afs_vlocation_cache_check_aux(void *cookie_netfs_data, | 
					
						
							|  |  |  | 						    const void *buffer, | 
					
						
							|  |  |  | 						    uint16_t buflen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct afs_cache_vlocation *cvldb; | 
					
						
							|  |  |  | 	struct afs_vlocation *vlocation = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t dlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check the size of the data is what we're expecting */ | 
					
						
							|  |  |  | 	dlen = sizeof(struct afs_cache_vlocation); | 
					
						
							|  |  |  | 	dlen -= offsetof(struct afs_cache_vlocation, nservers); | 
					
						
							|  |  |  | 	if (dlen != buflen) | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_OBSOLETE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cvldb = container_of(buffer, struct afs_cache_vlocation, nservers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if what's on disk is more valid than what's in memory, then use the
 | 
					
						
							|  |  |  | 	 * VL record from the cache */ | 
					
						
							|  |  |  | 	if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) { | 
					
						
							|  |  |  | 		memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen); | 
					
						
							|  |  |  | 		vlocation->valid = 1; | 
					
						
							|  |  |  | 		_leave(" = SUCCESS [c->m]"); | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_OKAY; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* need to update the cache if the cached info differs */ | 
					
						
							|  |  |  | 	if (memcmp(&vlocation->vldb, buffer, dlen) != 0) { | 
					
						
							|  |  |  | 		/* delete if the volume IDs for this name differ */ | 
					
						
							|  |  |  | 		if (memcmp(&vlocation->vldb.vid, &cvldb->vid, | 
					
						
							|  |  |  | 			   sizeof(cvldb->vid)) != 0 | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 		    ) { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 			_leave(" = OBSOLETE"); | 
					
						
							|  |  |  | 			return FSCACHE_CHECKAUX_OBSOLETE; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_leave(" = UPDATE"); | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_NEEDS_UPDATE; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_leave(" = OKAY"); | 
					
						
							|  |  |  | 	return FSCACHE_CHECKAUX_OKAY; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * set the key for the volume index entry | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					void *buffer, uint16_t bufmax) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_volume *volume = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t klen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%u},%p,%u", volume->type, buffer, bufmax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	klen = sizeof(volume->type); | 
					
						
							|  |  |  | 	if (klen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	memcpy(buffer, &volume->type, sizeof(volume->type)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_leave(" = %u", klen); | 
					
						
							|  |  |  | 	return klen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * set the key for the index entry | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					void *buffer, uint16_t bufmax) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_vnode *vnode = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t klen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_enter("{%x,%x,%llx},%p,%u", | 
					
						
							|  |  |  | 	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, | 
					
						
							|  |  |  | 	       buffer, bufmax); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	klen = sizeof(vnode->fid.vnode); | 
					
						
							|  |  |  | 	if (klen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(buffer, &vnode->fid.vnode, sizeof(vnode->fid.vnode)); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_leave(" = %u", klen); | 
					
						
							|  |  |  | 	return klen; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * provide updated file attributes | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static void afs_vnode_cache_get_attr(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 				     uint64_t *size) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	const struct afs_vnode *vnode = cookie_netfs_data; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_enter("{%x,%x,%llx},", | 
					
						
							|  |  |  | 	       vnode->fid.vnode, vnode->fid.unique, | 
					
						
							|  |  |  | 	       vnode->status.data_version); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	*size = vnode->status.size; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * provide new auxiliary cache data | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, | 
					
						
							|  |  |  | 					void *buffer, uint16_t bufmax) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct afs_vnode *vnode = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t dlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%x,%x,%Lx},%p,%u", | 
					
						
							|  |  |  | 	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, | 
					
						
							|  |  |  | 	       buffer, bufmax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version); | 
					
						
							|  |  |  | 	if (dlen > bufmax) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(buffer, &vnode->fid.unique, sizeof(vnode->fid.unique)); | 
					
						
							|  |  |  | 	buffer += sizeof(vnode->fid.unique); | 
					
						
							|  |  |  | 	memcpy(buffer, &vnode->status.data_version, | 
					
						
							|  |  |  | 	       sizeof(vnode->status.data_version)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_leave(" = %u", dlen); | 
					
						
							|  |  |  | 	return dlen; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  |  * check that the auxiliary data indicates that the entry is still valid | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, | 
					
						
							|  |  |  | 						       const void *buffer, | 
					
						
							|  |  |  | 						       uint16_t buflen) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	struct afs_vnode *vnode = cookie_netfs_data; | 
					
						
							|  |  |  | 	uint16_t dlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%x,%x,%llx},%p,%u", | 
					
						
							|  |  |  | 	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, | 
					
						
							|  |  |  | 	       buffer, buflen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check the size of the data is what we're expecting */ | 
					
						
							|  |  |  | 	dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version); | 
					
						
							|  |  |  | 	if (dlen != buflen) { | 
					
						
							|  |  |  | 		_leave(" = OBSOLETE [len %hx != %hx]", dlen, buflen); | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_OBSOLETE; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	if (memcmp(buffer, | 
					
						
							|  |  |  | 		   &vnode->fid.unique, | 
					
						
							|  |  |  | 		   sizeof(vnode->fid.unique) | 
					
						
							|  |  |  | 		   ) != 0) { | 
					
						
							|  |  |  | 		unsigned unique; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(&unique, buffer, sizeof(unique)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_leave(" = OBSOLETE [uniq %x != %x]", | 
					
						
							|  |  |  | 		       unique, vnode->fid.unique); | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_OBSOLETE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (memcmp(buffer + sizeof(vnode->fid.unique), | 
					
						
							|  |  |  | 		   &vnode->status.data_version, | 
					
						
							|  |  |  | 		   sizeof(vnode->status.data_version) | 
					
						
							|  |  |  | 		   ) != 0) { | 
					
						
							|  |  |  | 		afs_dataversion_t version; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(&version, buffer + sizeof(vnode->fid.unique), | 
					
						
							|  |  |  | 		       sizeof(version)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_leave(" = OBSOLETE [vers %llx != %llx]", | 
					
						
							|  |  |  | 		       version, vnode->status.data_version); | 
					
						
							|  |  |  | 		return FSCACHE_CHECKAUX_OBSOLETE; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_leave(" = SUCCESS"); | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	return FSCACHE_CHECKAUX_OKAY; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  |  * indication the cookie is no longer uncached | 
					
						
							|  |  |  |  * - this function is called when the backing store currently caching a cookie | 
					
						
							|  |  |  |  *   is removed | 
					
						
							|  |  |  |  * - the netfs should use this to clean up any markers indicating cached pages | 
					
						
							|  |  |  |  * - this is mandatory for any object that may have data | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | static void afs_vnode_cache_now_uncached(void *cookie_netfs_data) | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	struct afs_vnode *vnode = cookie_netfs_data; | 
					
						
							|  |  |  | 	struct pagevec pvec; | 
					
						
							|  |  |  | 	pgoff_t first; | 
					
						
							|  |  |  | 	int loop, nr_pages; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_enter("{%x,%x,%Lx}", | 
					
						
							|  |  |  | 	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pagevec_init(&pvec, 0); | 
					
						
							|  |  |  | 	first = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		/* grab a bunch of pages to clean */ | 
					
						
							|  |  |  | 		nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping, | 
					
						
							|  |  |  | 					  first, | 
					
						
							|  |  |  | 					  PAGEVEC_SIZE - pagevec_count(&pvec)); | 
					
						
							|  |  |  | 		if (!nr_pages) | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 		for (loop = 0; loop < nr_pages; loop++) | 
					
						
							|  |  |  | 			ClearPageFsCache(pvec.pages[loop]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		first = pvec.pages[nr_pages - 1]->index + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pvec.nr = nr_pages; | 
					
						
							|  |  |  | 		pagevec_release(&pvec); | 
					
						
							|  |  |  | 		cond_resched(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-03 16:42:41 +01:00
										 |  |  | 	_leave(""); | 
					
						
							| 
									
										
										
										
											2007-04-26 15:55:03 -07:00
										 |  |  | } |