/* Check a mount point for busyness return 1 if not busy, otherwise */
static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
{
	int status = 0;

	DPRINTK("dentry %p %.*s",
		dentry, (int)dentry->d_name.len, dentry->d_name.name);

	mntget(mnt);
	dget(dentry);

	if (!autofs4_follow_mount(&mnt, &dentry))
		goto done;

	/* This is an autofs submount, we can't expire it */
	if (is_autofs4_dentry(dentry))
		goto done;

	/* The big question */
	if (may_umount_tree(mnt) == 0)
		status = 1;
done:
	DPRINTK("returning = %d", status);
	mntput(mnt);
	dput(dentry);
	return status;
}
/* Check a mount point for busyness */
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
	struct dentry *top = dentry;
	struct path path = {.mnt = mnt, .dentry = dentry};
	int status = 1;

	DPRINTK("dentry %p %.*s",
		dentry, (int)dentry->d_name.len, dentry->d_name.name);

	path_get(&path);

	if (!follow_down_one(&path))
		goto done;

	if (is_autofs4_dentry(path.dentry)) {
		struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);

		/* This is an autofs submount, we can't expire it */
		if (autofs_type_indirect(sbi->type))
			goto done;
	}

	/* Update the expiry counter if fs is busy */
	if (!may_umount_tree(path.mnt)) {
		struct autofs_info *ino = autofs4_dentry_ino(top);
		ino->last_used = jiffies;
		goto done;
	}

	status = 0;
done:
	DPRINTK("returning = %d", status);
	path_put(&path);
	return status;
}
Пример #3
0
/* Check a mount point for busyness */
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
	struct dentry *top = dentry;
	int status = 1;

	DPRINTK("dentry %p %.*s",
		dentry, (int)dentry->d_name.len, dentry->d_name.name);

	mntget(mnt);
	dget(dentry);

	if (!autofs4_follow_mount(&mnt, &dentry))
		goto done;

	/* This is an autofs submount, we can't expire it */
	if (is_autofs4_dentry(dentry))
		goto done;

	/* Update the expiry counter if fs is busy */
	if (!may_umount_tree(mnt)) {
		struct autofs_info *ino = autofs4_dentry_ino(top);
		ino->last_used = jiffies;
		goto done;
	}

	status = 0;
done:
	DPRINTK("returning = %d", status);
	mntput(mnt);
	dput(dentry);
	return status;
}
Пример #4
0
/* Check a mount point for busyness */
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
	struct dentry *top = dentry;
	int status = 1;

	DPRINTK("dentry %p %.*s",
		dentry, (int)dentry->d_name.len, dentry->d_name.name);

	mntget(mnt);
	dget(dentry);

	if (!follow_down(&mnt, &dentry))
		goto done;

	if (is_autofs4_dentry(dentry)) {
		struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);

		/* This is an autofs submount, we can't expire it */
		if (autofs_type_indirect(sbi->type))
			goto done;

		/*
		 * Otherwise it's an offset mount and we need to check
		 * if we can umount its mount, if there is one.
		 */
		if (!d_mountpoint(dentry))
			goto done;
	}

	/* Update the expiry counter if fs is busy */
	if (!may_umount_tree(mnt)) {
		struct autofs_info *ino = autofs4_dentry_ino(top);
		ino->last_used = jiffies;
		goto done;
	}

	status = 0;
done:
	DPRINTK("returning = %d", status);
	dput(dentry);
	mntput(mnt);
	return status;
}
Пример #5
0
/* Check dentry tree for busyness.  If a dentry appears to be busy
   because it is a mountpoint, check to see if the mounted
   filesystem is busy. */
static int is_tree_busy(struct vfsmount *topmnt, struct dentry *top)
{
	struct dentry *this_parent;
	struct list_head *next;
	int count;

	count = atomic_read(&top->d_count);
	
	DPRINTK(("is_tree_busy: top=%p initial count=%d\n", 
		 top, count));
	this_parent = top;

	if (is_autofs4_dentry(top)) {
		count--;
		DPRINTK(("is_tree_busy: autofs; count=%d\n", count));
	}

	if (d_mountpoint(top))
		count -= check_vfsmnt(topmnt, top);

 repeat:
	next = this_parent->d_subdirs.next;
 resume:
	while (next != &this_parent->d_subdirs) {
		int adj = 0;
		struct dentry *dentry = list_entry(next, struct dentry,
						   d_child);
		next = next->next;

		count += atomic_read(&dentry->d_count) - 1;

		if (d_mountpoint(dentry))
			adj += check_vfsmnt(topmnt, dentry);

		if (is_autofs4_dentry(dentry)) {
			adj++;
			DPRINTK(("is_tree_busy: autofs; adj=%d\n",
				 adj));
		}

		count -= adj;

		if (!list_empty(&dentry->d_subdirs)) {
			this_parent = dentry;
			goto repeat;
		}

		if (atomic_read(&dentry->d_count) != adj) {
			DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n",
				 atomic_read(&dentry->d_count), adj));
			return 1;
		}
	}

	/* All done at this level ... ascend and resume the search. */
	if (this_parent != top) {
		next = this_parent->d_child.next; 
		this_parent = this_parent->d_parent;
		goto resume;
	}

	DPRINTK(("is_tree_busy: count=%d\n", count));
	return count != 0; /* remaining users? */
}