Пример #1
0
static int do_umount(struct vfsmount *mnt, int flags)
{
	struct super_block * sb = mnt->mnt_sb;
	int retval = 0;

	printk("do_umount\n");

	/*
	 * If we may have to abort operations to get out of this
	 * mount, and they will themselves hold resources we must
	 * allow the fs to do things. In the Unix tradition of
	 * 'Gee thats tricky lets do it in userspace' the umount_begin
	 * might fail to complete on the first run through as other tasks
	 * must return, and the like. Thats for the mount program to worry
	 * about for the moment.
	 */

	lock_kernel();
	if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
		sb->s_op->umount_begin(sb);
	unlock_kernel();

	spin_lock(&dcache_lock);

	if (atomic_read(&sb->s_active) == 1) {
		/* last instance - try to be smart */
		spin_unlock(&dcache_lock);
		lock_kernel();
		DQUOT_OFF(sb);
//		acct_auto_close(sb->s_dev);
		unlock_kernel();
		spin_lock(&dcache_lock);
	}
	retval = -EBUSY;
	if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
//		if (!list_empty(&mnt->mnt_list))
//			umount_tree(mnt);
			__mntput(mnt);    // free it --sadyc
		retval = 0;
	}
	spin_unlock(&dcache_lock);
	return retval;
}
Пример #2
0
/* do_emergency_sync helper function */
static void go_sync(struct super_block *sb, int remount_flag)
{
	int orig_loglevel;
	orig_loglevel = console_loglevel;
	console_loglevel = 7;
	printk(KERN_INFO "%sing device %s ... ",
	       remount_flag ? "Remount" : "Sync",
	       kdevname(sb->s_dev));

	if (remount_flag) { /* Remount R/O */
		int ret, flags;
		struct list_head *p;

		if (sb->s_flags & MS_RDONLY) {
			printk("R/O\n");
			return;
		}

		file_list_lock();
		for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
			struct file *file = list_entry(p, struct file, f_list);
			if (file->f_dentry && file_count(file)
				&& S_ISREG(file->f_dentry->d_inode->i_mode))
				file->f_mode &= ~2;
		}
		file_list_unlock();
		DQUOT_OFF(sb);
		fsync_dev(sb->s_dev);
		flags = MS_RDONLY;
		if (sb->s_op && sb->s_op->remount_fs) {
			ret = sb->s_op->remount_fs(sb, &flags, NULL);
			if (ret)
				printk("error %d\n", ret);
			else {
				sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
				printk("OK\n");
			}
		} else
			printk("nothing to do\n");
	} else { /* Sync only */
Пример #3
0
static void go_sync(kdev_t dev, int remount_flag)
{
	printk(KERN_INFO "%sing device %s ... ",
	       remount_flag ? "Remount" : "Sync",
	       kdevname(dev));

	if (remount_flag) {				    /* Remount R/O */
		struct super_block *sb = get_super(dev);
		struct vfsmount *vfsmnt;
		int ret, flags;

		if (!sb) {
			printk("Superblock not found\n");
			return;
		}
		if (sb->s_flags & MS_RDONLY) {
			printk("R/O\n");
			return;
		}
		DQUOT_OFF(dev);
		fsync_dev(dev);
		flags = MS_RDONLY;
		if (sb->s_op && sb->s_op->remount_fs) {
			ret = sb->s_op->remount_fs(sb, &flags, NULL);
			if (ret)
				printk("error %d\n", ret);
			else {
				sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
				if ((vfsmnt = lookup_vfsmnt(sb->s_dev)))
					vfsmnt->mnt_flags = sb->s_flags;
				printk("OK\n");
			}
		} else
			printk("nothing to do\n");
	} else {
		fsync_dev(dev);				    /* Sync only */
		printk("OK\n");
	}
}
Пример #4
0
static int do_umount(kdev_t dev, int unmount_root, int flags)
{
	struct super_block * sb;
	int retval;
	
	retval = -ENOENT;
	sb = get_super(dev);
	if (!sb || !sb->s_root)
		goto out;

	/*
	 * Before checking whether the filesystem is still busy,
	 * make sure the kernel doesn't hold any quota files open
	 * on the device. If the umount fails, too bad -- there
	 * are no quotas running any more. Just turn them on again.
	 */
	DQUOT_OFF(dev);
	acct_auto_close(dev);

	/*
	 * If we may have to abort operations to get out of this
	 * mount, and they will themselves hold resources we must
	 * allow the fs to do things. In the Unix tradition of
	 * 'Gee thats tricky lets do it in userspace' the umount_begin
	 * might fail to complete on the first run through as other tasks
	 * must return, and the like. Thats for the mount program to worry
	 * about for the moment.
	 */
	 
	if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
		sb->s_op->umount_begin(sb);

	/*
	 * Shrink dcache, then fsync. This guarantees that if the
	 * filesystem is quiescent at this point, then (a) only the
	 * root entry should be in use and (b) that root entry is
	 * clean.
	 */
	shrink_dcache_sb(sb);
	fsync_dev(dev);

	if (dev==ROOT_DEV && !unmount_root) {
		/*
		 * Special case for "unmounting" root ...
		 * we just try to remount it readonly.
		 */
		retval = 0;
		if (!(sb->s_flags & MS_RDONLY))
			retval = do_remount_sb(sb, MS_RDONLY, 0);
		return retval;
	}

	retval = d_umount(sb);
	if (retval)
		goto out;

	if (sb->s_op) {
		if (sb->s_op->write_super && sb->s_dirt)
			sb->s_op->write_super(sb);
	}

	lock_super(sb);
	if (sb->s_op) {
		if (sb->s_op->put_super)
			sb->s_op->put_super(sb);
	}

	/* Forget any remaining inodes */
	if (invalidate_inodes(sb)) {
		printk("VFS: Busy inodes after unmount. "
			"Self-destruct in 5 seconds.  Have a nice day...\n");
	}

	sb->s_dev = 0;		/* Free the superblock */
	unlock_super(sb);

	remove_vfsmnt(dev);
out:
	return retval;
}