Hi ...

  I have recently been upgrading to 5.0 [now on RELEASE!] and
I have one patch I've been applying which solves a problem
introduced by a change in ffs_mountfs() where a read-only
mount request insists on opening the device in R/W mode.
This is fine for the reasons it was done, but it means
you can't mount -o ro a ufs filesystem which is on a
read-only medium [e.g. a network disk replica or perhaps
a ufs filesystem on a CDROM]. Enclosed are suggested patches
which preserve the intent of the changes as of 5.0, but
allow a read-only mount on a read-only device to work as
well. If a mount is done with this, then mount -u -o rw is
not allowed. Needless to say, if you really want to mount
it for writing, you need to copy the image to a writable
medium. Enclosed are diffs [relative to 5.0-RELEASE].

--David

# diff -c ufs/ufs/ufsmount.h.orig ufs/ufs/ufsmount.h
*** ufs/ufs/ufsmount.h.orig     Sun Dec 29 09:54:20 2002
--- ufs/ufs/ufsmount.h  Wed Jan 15 12:10:43 2003
***************
*** 84,90 ****
--- 84,93 ----
        int     (*um_valloc)(struct vnode *, int, struct ucred *, struct vnode **);
        int     (*um_vfree)(struct vnode *, ino_t, int);
        void    (*um_ifree)(struct ufsmount *, struct inode *);
+       int     um_fmode;       /* FREAD or FREAD|FWRITE */
  };
+ 
+ #define __UFSMOUNT_FMODE__
  
  #define UFS_BALLOC(aa, bb, cc, dd, ee, ff) VFSTOUFS((aa)->v_mount)->um_balloc(aa, 
bb, cc, dd, ee, ff)
  #define UFS_BLKATOFF(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_blkatoff(aa, bb, 
cc, dd)

# diff -c ufs/ffs/ffs_vfsops.c.orig ufs/ffs/ffs_vfsops.c
*** ufs/ffs/ffs_vfsops.c.orig   Sun Dec 29 09:54:19 2002
--- ufs/ffs/ffs_vfsops.c        Wed Jan 15 12:14:33 2003
***************
*** 244,249 ****
--- 244,256 ----
                    (error = ffs_reload(mp, ndp->ni_cnd.cn_cred, td)) != 0)
                        return (error);
                if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
+ #if defined(__UFSMOUNT_FMODE__)
+                       /*
+                        * Disallow this if devvp is read-only ...
+                        */
+                       if (ump->um_fmode != (FREAD|FWRITE))
+                               return(EROFS);
+ #endif        /* defined(__UFSMOUNT_FMODE__) */
                        /*
                         * If upgrade to read-write by non-root, then verify
                         * that user has necessary permissions on the device.
***************
*** 569,574 ****
--- 576,584 ----
        struct ucred *cred;
        size_t strsize;
        int ncount;
+ #if defined(__UFSMOUNT_FMODE__)
+       int um_fmode = 0;
+ #endif        /* defined(__UFSMOUNT_FMODE__) */
  
        dev = devvp->v_rdev;
        cred = td ? td->td_ucred : NOCRED;
***************
*** 607,612 ****
--- 617,638 ----
  
        ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ #if defined(__UFSMOUNT_FMODE__)
+       /*
+        * Try to open R/W, but if that fails, try just for read
+        * but only if this is a read-only mount. We remember how
+        * we did this so that we can disallow upgrades to R/W
+        * if ump->um_fmode == FREAD.
+        */
+       um_fmode = FREAD|FWRITE;
+ again:
+       if ((error = VOP_OPEN(devvp, um_fmode, FSCRED, td)) != 0) {
+               if ((um_fmode != FREAD) && (ronly != 0)) {
+                       um_fmode = FREAD;
+                       goto again;
+               }
+       }
+ #else /* !defined(__UFSMOUNT_FMODE__) */
        /*
         * XXX: We don't re-VOP_OPEN in FREAD|FWRITE mode if the filesystem
         * XXX: is subsequently remounted, so open it FREAD|FWRITE from the
***************
*** 617,622 ****
--- 643,649 ----
  #else
        error = VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, td);
  #endif
+ #endif        /* !defined(__UFSMOUNT_FMODE__) */
        VOP_UNLOCK(devvp, 0, td);
        if (error)
                return (error);
***************
*** 687,692 ****
--- 714,722 ----
                fs->fs_pendinginodes = 0;
        }
        ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO);
+ #if defined(__UFSMOUNT_FMODE__)
+       ump->um_fmode = um_fmode;
+ #endif        /* defined(__UFSMOUNT_FMODE__) */
        ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
            M_WAITOK);
        if (fs->fs_magic == FS_UFS1_MAGIC) {
***************
*** 829,839 ****
--- 859,873 ----
        if (bp)
                brelse(bp);
        /* XXX: see comment above VOP_OPEN */
+ #if defined(__UFSMOUNT_FMODE__)
+       (void)VOP_CLOSE(devvp, um_fmode, cred, td);
+ #else /* !defined(__UFSMOUNT_FMODE__) */
  #ifdef notyet
        (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, td);
  #else
        (void)VOP_CLOSE(devvp, FREAD|FWRITE, cred, td);
  #endif
+ #endif        /* !defined(__UFSMOUNT_FMODE__) */
        if (ump) {
                free(ump->um_fs, M_UFSMNT);
                free(ump, M_UFSMNT);
***************
*** 988,993 ****
--- 1022,1030 ----
        ump->um_devvp->v_rdev->si_mountpoint = NULL;
  
        vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, td, 0, 0);
+ #if defined(__UFSMOUNT_FMODE__)
+       error = VOP_CLOSE(ump->um_devvp, ump->um_fmode, NOCRED, td);
+ #else /* !defined(__UFSMOUNT_FMODE__) */
        /* XXX: see comment above VOP_OPEN */
  #ifdef notyet
        error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
***************
*** 995,1000 ****
--- 1032,1038 ----
  #else
        error = VOP_CLOSE(ump->um_devvp, FREAD|FWRITE, NOCRED, td);
  #endif
+ #endif        /* !defined(__UFSMOUNT_FMODE__) */
  
        vrele(ump->um_devvp);
  

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to