diff options
Diffstat (limited to 'drivers/staging/autofs/dirhash.c')
| -rw-r--r-- | drivers/staging/autofs/dirhash.c | 250 | 
1 files changed, 0 insertions, 250 deletions
diff --git a/drivers/staging/autofs/dirhash.c b/drivers/staging/autofs/dirhash.c deleted file mode 100644 index 8f3e2b81612..00000000000 --- a/drivers/staging/autofs/dirhash.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/dirhash.c - * - *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include "autofs_i.h" - -/* Functions for maintenance of expiry queue */ - -static void autofs_init_usage(struct autofs_dirhash *dh, -			      struct autofs_dir_ent *ent) -{ -	list_add_tail(&ent->exp, &dh->expiry_head); -	ent->last_usage = jiffies; -} - -static void autofs_delete_usage(struct autofs_dir_ent *ent) -{ -	list_del(&ent->exp); -} - -void autofs_update_usage(struct autofs_dirhash *dh, -			 struct autofs_dir_ent *ent) -{ -	autofs_delete_usage(ent);   /* Unlink from current position */ -	autofs_init_usage(dh,ent);  /* Relink at queue tail */ -} - -struct autofs_dir_ent *autofs_expire(struct super_block *sb, -				     struct autofs_sb_info *sbi, -				     struct vfsmount *mnt) -{ -	struct autofs_dirhash *dh = &sbi->dirhash; -	struct autofs_dir_ent *ent; -	unsigned long timeout = sbi->exp_timeout; - -	while (1) { -		struct path path; -		int umount_ok; - -		if ( list_empty(&dh->expiry_head) || sbi->catatonic ) -			return NULL;	/* No entries */ -		/* We keep the list sorted by last_usage and want old stuff */ -		ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp); -		if (jiffies - ent->last_usage < timeout) -			break; -		/* Move to end of list in case expiry isn't desirable */ -		autofs_update_usage(dh, ent); - -		/* Check to see that entry is expirable */ -		if ( ent->ino < AUTOFS_FIRST_DIR_INO ) -			return ent; /* Symlinks are always expirable */ - -		/* Get the dentry for the autofs subdirectory */ -		path.dentry = ent->dentry; - -		if (!path.dentry) { -			/* Should only happen in catatonic mode */ -			printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name); -			autofs_delete_usage(ent); -			continue; -		} - -		if (!path.dentry->d_inode) { -			dput(path.dentry); -			printk("autofs: negative dentry on expiry queue: %s\n", -			       ent->name); -			autofs_delete_usage(ent); -			continue; -		} - -		/* Make sure entry is mounted and unused; note that dentry will -		   point to the mounted-on-top root. */ -		if (!S_ISDIR(path.dentry->d_inode->i_mode) || -		    !d_mountpoint(path.dentry)) { -			DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); -			continue; -		} -		path.mnt = mnt; -		path_get(&path); -		if (!follow_down(&path)) { -			path_put(&path); -			DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); -			continue; -		} -		while (d_mountpoint(path.dentry) && follow_down(&path)) -			; -		umount_ok = may_umount(path.mnt); -		path_put(&path); - -		if (umount_ok) { -			DPRINTK(("autofs: signaling expire on %s\n", ent->name)); -			return ent; /* Expirable! */ -		} -		DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name)); -	} -	return NULL;		/* No expirable entries */ -} - -void autofs_initialize_hash(struct autofs_dirhash *dh) { -	memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *)); -	INIT_LIST_HEAD(&dh->expiry_head); -} - -struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name) -{ -	struct autofs_dir_ent *dhn; - -	DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash)); -	autofs_say(name->name,name->len); - -	for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) { -		if ( name->hash == dhn->hash && -		     name->len == dhn->len && -		     !memcmp(name->name, dhn->name, name->len) ) -			break; -	} - -	return dhn; -} - -void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) -{ -	struct autofs_dir_ent **dhnp; - -	DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash)); -	autofs_say(ent->name,ent->len); - -	autofs_init_usage(dh,ent); -	if (ent->dentry) -		dget(ent->dentry); - -	dhnp = &dh->h[(unsigned) ent->hash % AUTOFS_HASH_SIZE]; -	ent->next = *dhnp; -	ent->back = dhnp; -	*dhnp = ent; -	if ( ent->next ) -		ent->next->back = &(ent->next); -} - -void autofs_hash_delete(struct autofs_dir_ent *ent) -{ -	*(ent->back) = ent->next; -	if ( ent->next ) -		ent->next->back = ent->back; - -	autofs_delete_usage(ent); - -	if ( ent->dentry ) -		dput(ent->dentry); -	kfree(ent->name); -	kfree(ent); -} - -/* - * Used by readdir().  We must validate "ptr", so we can't simply make it - * a pointer.  Values below 0xffff are reserved; calling with any value - * <= 0x10000 will return the first entry found. - * - * "last" can be NULL or the value returned by the last search *if* we - * want the next sequential entry. - */ -struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, -					off_t *ptr, struct autofs_dir_ent *last) -{ -	int bucket, ecount, i; -	struct autofs_dir_ent *ent; - -	bucket = (*ptr >> 16) - 1; -	ecount = *ptr & 0xffff; - -	if ( bucket < 0 ) { -		bucket = ecount = 0; -	}  - -	DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount)); - -	ent = last ? last->next : NULL; - -	if ( ent ) { -		ecount++; -	} else { -		while  ( bucket < AUTOFS_HASH_SIZE ) { -			ent = dh->h[bucket]; -			for ( i = ecount ; ent && i ; i-- ) -				ent = ent->next; -			 -			if (ent) { -				ecount++; /* Point to *next* entry */ -				break; -			} -			 -			bucket++; ecount = 0; -		} -	} - -#ifdef DEBUG -	if ( !ent ) -		printk("autofs_hash_enum: nothing found\n"); -	else { -		printk("autofs_hash_enum: found hash %08x, name", ent->hash); -		autofs_say(ent->name,ent->len); -	} -#endif - -	*ptr = ((bucket+1) << 16) + ecount; -	return ent; -} - -/* Iterate over all the ents, and remove all dentry pointers.  Used on -   entering catatonic mode, in order to make the filesystem unmountable. */ -void autofs_hash_dputall(struct autofs_dirhash *dh) -{ -	int i; -	struct autofs_dir_ent *ent; - -	for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { -		for ( ent = dh->h[i] ; ent ; ent = ent->next ) { -			if ( ent->dentry ) { -				dput(ent->dentry); -				ent->dentry = NULL; -			} -		} -	} -} - -/* Delete everything.  This is used on filesystem destruction, so we -   make no attempt to keep the pointers valid */ -void autofs_hash_nuke(struct autofs_sb_info *sbi) -{ -	int i; -	struct autofs_dir_ent *ent, *nent; - -	for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { -		for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) { -			nent = ent->next; -			if ( ent->dentry ) -				dput(ent->dentry); -			kfree(ent->name); -			kfree(ent); -		} -	} -}  | 
