Commit 087f757b authored by Steve French's avatar Steve French
Browse files

cifs: add shutdown support



Various filesystem support the shutdown ioctl which is used by various
xfstests. The shutdown ioctl sets a flag on the superblock which
prevents open, unlink, symlink, hardlink, rmdir, create etc.
on the file system until unmount and remounted. The two flags supported
in this patch are:

  FSOP_GOING_FLAGS_LOGFLUSH and FSOP_GOING_FLAGS_NOLOGFLUSH

which require very little other than blocking new operations (since
we do not cache writes to metadata on the client with cifs.ko).
FSOP_GOING_FLAGS_DEFAULT is not supported yet, but could be added in
the future but would need to call syncfs or equivalent to write out
pending data on the mount.

With this patch various xfstests now work including tests 043 through
046 for example.

Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Reviewed-by: default avatarAurelien Aptel <aaptel@suse.com>
parent c3f207ab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
#define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */
#define CIFS_MOUNT_RO_CACHE	0x20000000  /* assumes share will not change */
#define CIFS_MOUNT_RW_CACHE	0x40000000  /* assumes only client accessing */
#define CIFS_MOUNT_SHUTDOWN	0x80000000

struct cifs_sb_info {
	struct rb_root tlink_tree;
+16 −0
Original line number Diff line number Diff line
@@ -78,3 +78,19 @@ struct smb3_notify {
#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)
#define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify)
#define CIFS_IOC_SHUTDOWN _IOR ('X', 125, __u32)

/*
 * Flags for going down operation
 */
#define CIFS_GOING_FLAGS_DEFAULT                0x0     /* going down */
#define CIFS_GOING_FLAGS_LOGFLUSH               0x1     /* flush log but not data */
#define CIFS_GOING_FLAGS_NOLOGFLUSH             0x2     /* don't flush log nor data */

static inline bool cifs_forced_shutdown(struct cifs_sb_info *sbi)
{
	if (CIFS_MOUNT_SHUTDOWN & sbi->mnt_cifs_flags)
		return true;
	else
		return false;
}
+10 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include "cifs_fs_sb.h"
#include "cifs_unicode.h"
#include "fs_context.h"
#include "cifs_ioctl.h"

static void
renew_parental_timestamps(struct dentry *direntry)
@@ -429,6 +430,9 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
	__u32 oplock;
	struct cifsFileInfo *file_info;

	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
		return -EIO;

	/*
	 * Posix open is only called (at lookup time) for file create now. For
	 * opens (rather than creates), because we do not know if it is a file
@@ -545,6 +549,9 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
	cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
		 inode, direntry, direntry);

	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
		return -EIO;

	tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
	rc = PTR_ERR(tlink);
	if (IS_ERR(tlink))
@@ -582,6 +589,9 @@ int cifs_mknod(struct user_namespace *mnt_userns, struct inode *inode,
		return -EINVAL;

	cifs_sb = CIFS_SB(inode->i_sb);
	if (unlikely(cifs_forced_shutdown(cifs_sb)))
		return -EIO;

	tlink = cifs_sb_tlink(cifs_sb);
	if (IS_ERR(tlink))
		return PTR_ERR(tlink);
+6 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include "fscache.h"
#include "smbdirect.h"
#include "fs_context.h"
#include "cifs_ioctl.h"

static inline int cifs_convert_flags(unsigned int flags)
{
@@ -542,6 +543,11 @@ int cifs_open(struct inode *inode, struct file *file)
	xid = get_xid();

	cifs_sb = CIFS_SB(inode->i_sb);
	if (unlikely(cifs_forced_shutdown(cifs_sb))) {
		free_xid(xid);
		return -EIO;
	}

	tlink = cifs_sb_tlink(cifs_sb);
	if (IS_ERR(tlink)) {
		free_xid(xid);
+1 −0
Original line number Diff line number Diff line
@@ -1642,6 +1642,7 @@ void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb)
			cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
		}
	}
	cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SHUTDOWN;

	return;
}
Loading