Whamcloud - gitweb
LU-9074 llite: Stop file creation for ro bind mnt 04/25204/12
authorNoopur Maheshwari <noopur.maheshwari@seagate.com>
Thu, 2 Feb 2017 09:09:31 +0000 (14:39 +0530)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 19 Jun 2017 16:27:49 +0000 (16:27 +0000)
While remounting the bind mount of lustre with read-only, vfs
sets MNT_READONLY in the mnt flags and does not make a call
to lustre. Hence, the change in mnt flags is not reflected in
lustre.

Therefore, file creation goes ahead in lookup operation of
lustre with LOOKUP_CREATE intent set and converted to IT_CREAT.

The fix is to disallow file creation by not setting IT_CREAT
intent when bind mnt pt is readonly and unsetting O_CREAT.

Added a test case to test that files are not created in ro
bind mount point. Files must be created after bind mount point
is converted from ro to rw.

Signed-off-by: Noopur Maheshwari <noopur.maheshwari@seagate.com>
Change-Id: Ic60fb18f539159715049515e264afdf51a00378e
Reviewed-on: https://review.whamcloud.com/25204
Reviewed-by: Andrew Perepechko <andrew.perepechko@seagate.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/namei.c
lustre/tests/conf-sanity.sh

index c8bfe98..ef60461 100644 (file)
@@ -804,7 +804,7 @@ out_release:
 
 #else /* !HAVE_IOP_ATOMIC_OPEN */
 static struct lookup_intent *
-ll_convert_intent(struct open_intent *oit, int lookup_flags)
+ll_convert_intent(struct open_intent *oit, int lookup_flags, bool is_readonly)
 {
        struct lookup_intent *it;
 
@@ -814,10 +814,12 @@ ll_convert_intent(struct open_intent *oit, int lookup_flags)
 
        if (lookup_flags & LOOKUP_OPEN) {
                it->it_op = IT_OPEN;
-               if (lookup_flags & LOOKUP_CREATE)
+               /* Avoid file creation for ro bind mount point(is_readonly) */
+               if ((lookup_flags & LOOKUP_CREATE) && !is_readonly)
                        it->it_op |= IT_CREAT;
                it->it_create_mode = (oit->create_mode & S_IALLUGO) | S_IFREG;
-               it->it_flags = ll_namei_to_lookup_intent_flag(oit->flags);
+               it->it_flags = ll_namei_to_lookup_intent_flag(oit->flags &
+                                               ~(is_readonly ? O_CREAT : 0));
                it->it_flags &= ~MDS_OPEN_FL_INTERNAL;
        } else {
                it->it_op = IT_GETATTR;
@@ -851,7 +853,9 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
                                              MAY_WRITE | MAY_EXEC) == 0))
                                RETURN(NULL);
 
-                       it = ll_convert_intent(&nd->intent.open, nd->flags);
+                       it = ll_convert_intent(&nd->intent.open, nd->flags,
+                               (nd->path.mnt->mnt_flags & MNT_READONLY) ||
+                               (nd->path.mnt->mnt_sb->s_flags & MS_RDONLY));
                        if (IS_ERR(it))
                                RETURN((struct dentry *)it);
                }
index 4c1a314..4bca875 100755 (executable)
@@ -7416,6 +7416,43 @@ test_104() { # LU-6952
 }
 run_test 104 "Make sure user defined options are reflected in mount"
 
+error_and_umount() {
+       umount $TMP/$tdir
+       rmdir $TMP/$tdir
+       error $*
+}
+
+test_105() {
+       cleanup
+       reformat
+       setup
+       mkdir -p $TMP/$tdir
+       mount --bind $DIR $TMP/$tdir || error "mount bind mnt pt failed"
+       rm -f $TMP/$tdir/$tfile
+       rm -f $TMP/$tdir/${tfile}1
+
+       # Files should not be created in ro bind mount point
+       # remounting from rw to ro
+       mount -o remount,ro $TMP/$tdir ||
+               error_and_umount "readonly remount of bind mnt pt failed"
+       touch $TMP/$tdir/$tfile &&
+               error_and_umount "touch succeeds on ro bind mnt pt"
+       [ -e $TMP/$tdir/$tfile ] &&
+               error_and_umount "file created on ro bind mnt pt"
+
+       # Files should be created in rw bind mount point
+       # remounting from ro to rw
+       mount -o remount,rw $TMP/$tdir ||
+               error_and_umount "read-write remount of bind mnt pt failed"
+       touch $TMP/$tdir/${tfile}1 ||
+               error_and_umount "touch fails on rw bind mnt pt"
+       [ -e $TMP/$tdir/${tfile}1 ] ||
+               error_and_umount "file not created on rw bind mnt pt"
+       umount $TMP/$tdir || error "umount of bind mnt pt failed"
+       rmdir $TMP/$tdir
+}
+run_test 105 "check file creation for ro and rw bind mnt pt"
+
 if ! combined_mgs_mds ; then
        stop mgs
 fi