Message ID | CAH2r5mvKfohJ=NkkCM7AxqRYq2+D8kRMTxP3VdG=W0s72Cdh0A@mail.gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | cifs: add shutdown support | expand |
Do we need to add code to clear the flag on remount or is it implicitely cleared by not copying it? Steve French <smfrench@gmail.com> writes: > #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 SMB3_MOUNT_SHUTDOWN 0x80000000 While I totally understand wanting to remove the "cifs" name, those flags are specific to the kernel & filesystem and have nothing to do with the wire protocol so in this case I would rather use CIFS_ prefix because SMB3_ is misleading and all the other flags are already using CIFS_. One day we should do s/CIFS/SMBFS/i on the whole tree where CIFS refers to kernel stuff (not protocol) and rename the module smbfs. But that's a story for another day I guess. > > struct cifs_sb_info { > struct rb_root tlink_tree; > diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h > index 153d5c842a9b..a744022d2a71 100644 > --- a/fs/cifs/cifs_ioctl.h > +++ b/fs/cifs/cifs_ioctl.h > @@ -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 SMB3_IOC_SHUTDOWN _IOR ('X', 125, __u32) Same > + > +/* > + * Flags for going down operation > + */ > +#define SMB3_GOING_FLAGS_DEFAULT 0x0 /* going down */ > +#define SMB3_GOING_FLAGS_LOGFLUSH 0x1 /* flush log > but not data */ > +#define SMB3_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't Same > flush log nor data */ > + > +static inline bool smb3_forced_shutdown(struct cifs_sb_info *sbi) Same > + cifs_dbg(VFS, "shut down requested (%d)", flags); /* BB FIXME */ > +/* trace_smb3_shutdown(sb, flags);*/ What is there to fix? It's doing like ext4 so it's fine no? > + > + /* > + * see: > + * https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html > + * for more information and description of original intent of the flags > + */ > + switch (flags) { > + /* > + * We could add support later for default flag which requires: > + * "Flush all dirty data and metadata to disk" > + * would need to call syncfs or equivalent to flush page cache for > + * the mount and then issue fsync to server (if nostrictsync not set) > + */ > + case SMB3_GOING_FLAGS_DEFAULT: > + cifs_dbg(VFS, "default flags\n"); Should this be removed, less verbose or more info should be printed? Cheers,
You are correct - I have to add the code to clear the bit on remount I have added your other changes and will send updated patch after lunch root@smfrench-ThinkPad-P52:~# mount | grep cifs //localhost/test on /mnt1 type cifs (rw,relatime,vers=3.1.1,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,noperm,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1) root@smfrench-ThinkPad-P52:~# touch /mnt1/file root@smfrench-ThinkPad-P52:~# ~smfrench/xfstests-dev/src/godown /mnt1/ root@smfrench-ThinkPad-P52:~# touch /mnt1/file touch: cannot touch '/mnt1/file': Input/output error root@smfrench-ThinkPad-P52:~# mount -o remount /mnt1 root@smfrench-ThinkPad-P52:~# touch /mnt1/file touch: cannot touch '/mnt1/file': Input/output error On Thu, Apr 29, 2021 at 4:29 AM Aurélien Aptel <aaptel@suse.com> wrote: > > > Do we need to add code to clear the flag on remount or is it implicitely > cleared by not copying it? > > Steve French <smfrench@gmail.com> writes: > > #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 SMB3_MOUNT_SHUTDOWN 0x80000000 > > While I totally understand wanting to remove the "cifs" name, those > flags are specific to the kernel & filesystem and have nothing to do > with the wire protocol so in this case I would rather use CIFS_ prefix > because SMB3_ is misleading and all the other flags are already using CIFS_. > > One day we should do s/CIFS/SMBFS/i on the whole tree where CIFS refers > to kernel stuff (not protocol) and rename the module smbfs. But that's a > story for another day I guess. > > > > > struct cifs_sb_info { > > struct rb_root tlink_tree; > > diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h > > index 153d5c842a9b..a744022d2a71 100644 > > --- a/fs/cifs/cifs_ioctl.h > > +++ b/fs/cifs/cifs_ioctl.h > > @@ -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 SMB3_IOC_SHUTDOWN _IOR ('X', 125, __u32) > > Same > > > + > > +/* > > + * Flags for going down operation > > + */ > > +#define SMB3_GOING_FLAGS_DEFAULT 0x0 /* going down */ > > +#define SMB3_GOING_FLAGS_LOGFLUSH 0x1 /* flush log > > but not data */ > > +#define SMB3_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't > > Same > > > flush log nor data */ > > + > > +static inline bool smb3_forced_shutdown(struct cifs_sb_info *sbi) > > Same > > > + cifs_dbg(VFS, "shut down requested (%d)", flags); /* BB FIXME */ > > +/* trace_smb3_shutdown(sb, flags);*/ > > What is there to fix? It's doing like ext4 so it's fine no? > > > + > > + /* > > + * see: > > + * https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html > > + * for more information and description of original intent of the flags > > + */ > > + switch (flags) { > > + /* > > + * We could add support later for default flag which requires: > > + * "Flush all dirty data and metadata to disk" > > + * would need to call syncfs or equivalent to flush page cache for > > + * the mount and then issue fsync to server (if nostrictsync not set) > > + */ > > + case SMB3_GOING_FLAGS_DEFAULT: > > + cifs_dbg(VFS, "default flags\n"); > > Should this be removed, less verbose or more info should be printed? > > Cheers, > -- > Aurélien Aptel / SUSE Labs Samba Team > GPG: 1839 CB5F 9F5B FB9B AA97 8C99 03C8 A49B 521B D5D3 > SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg, DE > GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 247165 (AG München) >
Updated patch attached. Fixed the remount issue (remount should clear the shutdown flag). See below simple demonstration: root@smfrench-ThinkPad-P52:~# mount | grep cifs //localhost/test on /mnt1 type cifs (rw,relatime,vers=3.1.1,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,noperm,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1) root@smfrench-ThinkPad-P52:~# touch /mnt1/file root@smfrench-ThinkPad-P52:~# ~smfrench/xfstests-dev/src/godown /mnt1/ root@smfrench-ThinkPad-P52:~# touch /mnt1/file touch: cannot touch '/mnt1/file': Input/output error root@smfrench-ThinkPad-P52:~# mount -t cifs //localhost/test /mnt1 -o remount root@smfrench-ThinkPad-P52:~# touch /mnt1/file On Thu, Apr 29, 2021 at 1:39 PM Steve French <smfrench@gmail.com> wrote: > > You are correct - I have to add the code to clear the bit on remount > > I have added your other changes and will send updated patch after lunch > > root@smfrench-ThinkPad-P52:~# mount | grep cifs > //localhost/test on /mnt1 type cifs > (rw,relatime,vers=3.1.1,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,noperm,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1) > root@smfrench-ThinkPad-P52:~# touch /mnt1/file > root@smfrench-ThinkPad-P52:~# ~smfrench/xfstests-dev/src/godown /mnt1/ > root@smfrench-ThinkPad-P52:~# touch /mnt1/file > touch: cannot touch '/mnt1/file': Input/output error > root@smfrench-ThinkPad-P52:~# mount -o remount /mnt1 > root@smfrench-ThinkPad-P52:~# touch /mnt1/file > touch: cannot touch '/mnt1/file': Input/output error > > On Thu, Apr 29, 2021 at 4:29 AM Aurélien Aptel <aaptel@suse.com> wrote: > > > > > > Do we need to add code to clear the flag on remount or is it implicitely > > cleared by not copying it? > > > > Steve French <smfrench@gmail.com> writes: > > > #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 SMB3_MOUNT_SHUTDOWN 0x80000000 > > > > While I totally understand wanting to remove the "cifs" name, those > > flags are specific to the kernel & filesystem and have nothing to do > > with the wire protocol so in this case I would rather use CIFS_ prefix > > because SMB3_ is misleading and all the other flags are already using CIFS_. > > > > One day we should do s/CIFS/SMBFS/i on the whole tree where CIFS refers > > to kernel stuff (not protocol) and rename the module smbfs. But that's a > > story for another day I guess. > > > > > > > > struct cifs_sb_info { > > > struct rb_root tlink_tree; > > > diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h > > > index 153d5c842a9b..a744022d2a71 100644 > > > --- a/fs/cifs/cifs_ioctl.h > > > +++ b/fs/cifs/cifs_ioctl.h > > > @@ -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 SMB3_IOC_SHUTDOWN _IOR ('X', 125, __u32) > > > > Same > > > > > + > > > +/* > > > + * Flags for going down operation > > > + */ > > > +#define SMB3_GOING_FLAGS_DEFAULT 0x0 /* going down */ > > > +#define SMB3_GOING_FLAGS_LOGFLUSH 0x1 /* flush log > > > but not data */ > > > +#define SMB3_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't > > > > Same > > > > > flush log nor data */ > > > + > > > +static inline bool smb3_forced_shutdown(struct cifs_sb_info *sbi) > > > > Same > > > > > + cifs_dbg(VFS, "shut down requested (%d)", flags); /* BB FIXME */ > > > +/* trace_smb3_shutdown(sb, flags);*/ > > > > What is there to fix? It's doing like ext4 so it's fine no? > > > > > + > > > + /* > > > + * see: > > > + * https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html > > > + * for more information and description of original intent of the flags > > > + */ > > > + switch (flags) { > > > + /* > > > + * We could add support later for default flag which requires: > > > + * "Flush all dirty data and metadata to disk" > > > + * would need to call syncfs or equivalent to flush page cache for > > > + * the mount and then issue fsync to server (if nostrictsync not set) > > > + */ > > > + case SMB3_GOING_FLAGS_DEFAULT: > > > + cifs_dbg(VFS, "default flags\n"); > > > > Should this be removed, less verbose or more info should be printed? > > > > Cheers, > > -- > > Aurélien Aptel / SUSE Labs Samba Team > > GPG: 1839 CB5F 9F5B FB9B AA97 8C99 03C8 A49B 521B D5D3 > > SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg, DE > > GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 247165 (AG München) > > > > > -- > Thanks, > > Steve
Hi, Steve French <smfrench@gmail.com> writes: > Updated patch attached. Fixed the remount issue (remount should > clear the shutdown flag). See below simple demonstration: I think it looks OK Reviewed-by: Aurelien Aptel <aaptel@suse.com> Cheers,
From e6e3c8dd9861fc977969d71703e776b51cf7fd4a Mon Sep 17 00:00:00 2001 From: Steve French <stfrench@microsoft.com> Date: Thu, 29 Apr 2021 00:18:43 -0500 Subject: [PATCH] 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: Steve French <stfrench@microsoft.com> --- fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifs_ioctl.h | 16 +++++++++++++ fs/cifs/dir.c | 10 +++++++++ fs/cifs/file.c | 6 +++++ fs/cifs/inode.c | 25 +++++++++++++++++++-- fs/cifs/ioctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/link.c | 7 ++++++ fs/cifs/xattr.c | 4 ++++ 8 files changed, 120 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 2a5325a7ae49..05de08143fcd 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -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 SMB3_MOUNT_SHUTDOWN 0x80000000 struct cifs_sb_info { struct rb_root tlink_tree; diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h index 153d5c842a9b..a744022d2a71 100644 --- a/fs/cifs/cifs_ioctl.h +++ b/fs/cifs/cifs_ioctl.h @@ -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 SMB3_IOC_SHUTDOWN _IOR ('X', 125, __u32) + +/* + * Flags for going down operation + */ +#define SMB3_GOING_FLAGS_DEFAULT 0x0 /* going down */ +#define SMB3_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ +#define SMB3_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ + +static inline bool smb3_forced_shutdown(struct cifs_sb_info *sbi) +{ + if (SMB3_MOUNT_SHUTDOWN & sbi->mnt_cifs_flags) + return true; + else + return false; +} diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 03afad8b24af..bc06a2dc6057 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -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(smb3_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(smb3_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(smb3_forced_shutdown(cifs_sb))) + return -EIO; + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5058252eeae6..bddeca06da08 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -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(smb3_forced_shutdown(cifs_sb))) { + free_xid(xid); + return -EIO; + } + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { free_xid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index baa9ffb4c446..35020686c66a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -26,7 +26,6 @@ #include <linux/sched/signal.h> #include <linux/wait_bit.h> #include <linux/fiemap.h> - #include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" @@ -38,7 +37,7 @@ #include "cifs_unicode.h" #include "fscache.h" #include "fs_context.h" - +#include "cifs_ioctl.h" static void cifs_set_ops(struct inode *inode) { @@ -1623,6 +1622,9 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry); + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -1876,6 +1878,8 @@ int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode, mode, inode); cifs_sb = CIFS_SB(inode->i_sb); + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -1958,6 +1962,11 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) } cifs_sb = CIFS_SB(inode->i_sb); + if (unlikely(smb3_forced_shutdown(cifs_sb))) { + rc = -EIO; + goto rmdir_exit; + } + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); @@ -2092,6 +2101,9 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, return -EINVAL; cifs_sb = CIFS_SB(source_dir->i_sb); + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -2409,6 +2421,9 @@ int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path, struct inode *inode = d_inode(dentry); int rc; + if (unlikely(smb3_forced_shutdown(CIFS_SB(inode->i_sb)))) + return -EIO; + /* * We need to be sure that all dirty pages are written and the server * has actual ctime, mtime and file length. @@ -2481,6 +2496,9 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, struct cifsFileInfo *cfile; int rc; + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + /* * We need to be sure that all dirty pages are written as they * might fill holes on the server. @@ -2967,6 +2985,9 @@ cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry, struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); int rc, retries = 0; + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + do { if (pTcon->unix_ext) rc = cifs_setattr_unix(direntry, attrs); diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 08d99fec593e..b34fa6a51a7b 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -164,6 +164,56 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, return rc; } +static int smb3_shutdown(struct super_block *sb, unsigned long arg) +{ + struct cifs_sb_info *sbi = CIFS_SB(sb); + __u32 flags; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (get_user(flags, (__u32 __user *)arg)) + return -EFAULT; + + if (flags > SMB3_GOING_FLAGS_NOLOGFLUSH) + return -EINVAL; + + if (smb3_forced_shutdown(sbi)) + return 0; + + cifs_dbg(VFS, "shut down requested (%d)", flags); /* BB FIXME */ +/* trace_smb3_shutdown(sb, flags);*/ + + /* + * see: + * https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html + * for more information and description of original intent of the flags + */ + switch (flags) { + /* + * We could add support later for default flag which requires: + * "Flush all dirty data and metadata to disk" + * would need to call syncfs or equivalent to flush page cache for + * the mount and then issue fsync to server (if nostrictsync not set) + */ + case SMB3_GOING_FLAGS_DEFAULT: + cifs_dbg(VFS, "default flags\n"); + return -EINVAL; + /* + * FLAGS_LOGFLUSH is easy since it asks to write out metadata (not + * data) but metadata writes are not cached on the client, so can treat + * it similarly to NOLOGFLUSH + */ + case SMB3_GOING_FLAGS_LOGFLUSH: + case SMB3_GOING_FLAGS_NOLOGFLUSH: + sbi->mnt_cifs_flags |= SMB3_MOUNT_SHUTDOWN; + return 0; + default: + return -EINVAL; + } + return 0; +} + long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) { struct inode *inode = file_inode(filep); @@ -325,6 +375,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) rc = -EOPNOTSUPP; cifs_put_tlink(tlink); break; + case SMB3_IOC_SHUTDOWN: + rc = smb3_shutdown(inode->i_sb, arg); + break; default: cifs_dbg(FYI, "unsupported ioctl\n"); break; diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 616e1bc0cc0a..ef2e9d2c155d 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -30,6 +30,7 @@ #include "cifs_fs_sb.h" #include "cifs_unicode.h" #include "smb2proto.h" +#include "cifs_ioctl.h" /* * M-F Symlink Functions - Begin @@ -518,6 +519,9 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, struct TCP_Server_Info *server; struct cifsInodeInfo *cifsInode; + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -682,6 +686,9 @@ cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode, void *page = alloc_dentry_path(); struct inode *newinode = NULL; + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + xid = get_xid(); tlink = cifs_sb_tlink(cifs_sb); diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index e351b945135b..c13f93e0e81b 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -30,6 +30,7 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" #include "cifs_unicode.h" +#include "cifs_ioctl.h" #define MAX_EA_VALUE_SIZE CIFSMaxBufSize #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" /* DACL only */ @@ -421,6 +422,9 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) const char *full_path; void *page; + if (unlikely(smb3_forced_shutdown(cifs_sb))) + return -EIO; + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) return -EOPNOTSUPP; -- 2.27.0
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. See https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html for a description of the flags With this patch various xfstests now work including tests 043 through 046 for example. Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifs_ioctl.h | 16 +++++++++++++ fs/cifs/dir.c | 10 +++++++++ fs/cifs/file.c | 6 +++++ fs/cifs/inode.c | 25 +++++++++++++++++++-- fs/cifs/ioctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/link.c | 7 ++++++ fs/cifs/xattr.c | 4 ++++ 8 files changed, 120 insertions(+), 2 deletions(-)