Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/bouyer-quota2]: src/sys Add a new inode flag, SF_SNAPINVAL, to be set on...



details:   https://anonhg.NetBSD.org/src/rev/4d2c80a753bc
branches:  bouyer-quota2
changeset: 761190:4d2c80a753bc
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Feb 18 19:54:44 2011 +0000

description:
Add a new inode flag, SF_SNAPINVAL, to be set on SF_SNAPSHOT inodes when
the snapshot is invalid.
Set SF_SNAPSHOT | SF_SNAPINVAL early when initializing a snapshot indode,
so that quota are bypassed for allocations on this inode.
Set SF_SNAPSHOT | SF_SNAPINVAL (instead of clearing SF_SNAPSHOT) when
expuge()ing a snapshot inode, so that userland tools working on the
snapshot (e.g. fsck or dump) can properly handle this inode.

The main point at this time is to have fsck_ffs -X properly compute quotas;
as a bonus persistent snapshots files won't show up in a dump(8) from a
snapshot.

This may also help speeding up taking snapshots, by bypassing expuge()
for snapshot inodes completely (but this needs more thoughs).


Briefly discussed with hannken@ in private mail.

diffstat:

 sys/sys/stat.h              |   3 +-
 sys/ufs/ffs/ffs_snapshot.c  |  64 +++++++++++++++++++++++++++++---------------
 sys/ufs/ufs/ufs_bmap.c      |  17 +++++++----
 sys/ufs/ufs/ufs_readwrite.c |   6 ++--
 sys/ufs/ufs/ufs_vnops.c     |   8 ++--
 5 files changed, 61 insertions(+), 37 deletions(-)

diffs (279 lines):

diff -r 8103687cd289 -r 4d2c80a753bc sys/sys/stat.h
--- a/sys/sys/stat.h    Fri Feb 18 19:05:45 2011 +0000
+++ b/sys/sys/stat.h    Fri Feb 18 19:54:44 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: stat.h,v 1.59 2009/08/27 07:28:42 mouse Exp $  */
+/*     $NetBSD: stat.h,v 1.59.8.1 2011/02/18 19:54:44 bouyer Exp $     */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -195,6 +195,7 @@
 /*     SF_NOUNLINK     0x00100000         [NOT IMPLEMENTED] */
 #define        SF_SNAPSHOT     0x00200000      /* snapshot inode */
 #define        SF_LOG          0x00400000      /* WAPBL log file inode */
+#define        SF_SNAPINVAL    0x00800000      /* snapshot is invalid */
 
 #ifdef _KERNEL
 /*
diff -r 8103687cd289 -r 4d2c80a753bc sys/ufs/ffs/ffs_snapshot.c
--- a/sys/ufs/ffs/ffs_snapshot.c        Fri Feb 18 19:05:45 2011 +0000
+++ b/sys/ufs/ffs/ffs_snapshot.c        Fri Feb 18 19:54:44 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ffs_snapshot.c,v 1.102.4.6 2011/02/18 09:51:16 bouyer Exp $    */
+/*     $NetBSD: ffs_snapshot.c,v 1.102.4.7 2011/02/18 19:54:44 bouyer Exp $    */
 
 /*
  * Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102.4.6 2011/02/18 09:51:16 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102.4.7 2011/02/18 19:54:44 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -194,7 +194,7 @@
        /*
         * If the vnode already is a snapshot, return.
         */
-       if (VTOI(vp)->i_flags & SF_SNAPSHOT) {
+       if ((VTOI(vp)->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) == SF_SNAPSHOT) {
                if (ctime) {
                        ctime->tv_sec = DIP(VTOI(vp), mtime);
                        ctime->tv_nsec = DIP(VTOI(vp), mtimensec);
@@ -215,18 +215,6 @@
        error = snapshot_setup(mp, vp);
        if (error)
                goto out;
-       /* shapshot inodes are not accounted in quotas */
-#if defined(QUOTA) || defined(QUOTA2)
-       chkdq(ip, -DIP(ip, blocks), l->l_cred, 0);
-       chkiq(ip, -1, l->l_cred, 0);
-#endif
-       /*
-        * Change inode to snapshot type file.
-        */
-       ip->i_flags |= SF_SNAPSHOT;
-       DIP_ASSIGN(ip, flags, ip->i_flags);
-       ip->i_flag |= IN_CHANGE | IN_UPDATE;
-
 
        /*
         * Copy all the cylinder group maps. Although the
@@ -239,6 +227,14 @@
        error = cgaccount(vp, 1, NULL);
        if (error)
                goto out;
+
+       /*
+        * snapshot is now valid
+        */
+       ip->i_flags &= ~SF_SNAPINVAL;
+       DIP_ASSIGN(ip, flags, ip->i_flags);
+       ip->i_flag |= IN_CHANGE | IN_UPDATE;
+
        /*
         * Ensure that the snapshot is completely on disk.
         * Since we have marked it as a snapshot it is safe to
@@ -418,6 +414,7 @@
        struct fs *fs = VFSTOUFS(mp)->um_fs;
        struct lwp *l = curlwp;
        const int wbreak = blocks_in_journal(fs)/8;
+       struct inode *ip = VTOI(vp);
 
        /*
         * Check mount, exclusive reference and owner.
@@ -436,6 +433,22 @@
                if (error)
                        return error;
        }
+
+       /* Change inode to snapshot type file. */
+       error = UFS_WAPBL_BEGIN(mp);
+       if (error)
+               return error;
+#if defined(QUOTA) || defined(QUOTA2)
+       /* shapshot inodes are not accounted in quotas */
+       chkiq(ip, -1, l->l_cred, 0);
+#endif
+       ip->i_flags |= (SF_SNAPSHOT | SF_SNAPINVAL);
+       DIP_ASSIGN(ip, flags, ip->i_flags);
+       ip->i_flag |= IN_CHANGE | IN_UPDATE;
+       ffs_update(vp, NULL, NULL, UPDATE_WAIT);
+       UFS_WAPBL_END(mp);
+
+       KASSERT(ip->i_flags & SF_SNAPSHOT);
        /*
         * Write an empty list of preallocated blocks to the end of
         * the snapshot to set size to at least that of the filesystem.
@@ -571,7 +584,7 @@
 snapshot_expunge(struct mount *mp, struct vnode *vp, struct fs *copy_fs,
     daddr_t *snaplistsize, daddr_t **snaplist)
 {
-       int cg, error, len, loc;
+       int cg, error = 0, len, loc;
        daddr_t blkno, *blkp;
        struct fs *fs = VFSTOUFS(mp)->um_fs;
        struct inode *xp;
@@ -1044,22 +1057,28 @@
        if (fs->fs_magic == FS_UFS1_MAGIC) {
                dip1 = (struct ufs1_dinode *)bp->b_data +
                    ino_to_fsbo(fs, cancelip->i_number);
+               if (cancelip->i_flags & SF_SNAPSHOT) {
+                       dip1->di_flags =
+                           ufs_rw32(ufs_rw32(dip1->di_flags, ns) |
+                           SF_SNAPINVAL, ns);
+               }
                if (expungetype == BLK_NOCOPY || cancelip->i_nlink == 0)
                        dip1->di_mode = 0;
                dip1->di_size = 0;
                dip1->di_blocks = 0;
-               dip1->di_flags =
-                   ufs_rw32(ufs_rw32(dip1->di_flags, ns) & ~SF_SNAPSHOT, ns);
                memset(&dip1->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int32_t));
        } else {
                dip2 = (struct ufs2_dinode *)bp->b_data +
                    ino_to_fsbo(fs, cancelip->i_number);
+               if (cancelip->i_flags & SF_SNAPSHOT) {
+                       dip2->di_flags =
+                           ufs_rw32(ufs_rw32(dip2->di_flags, ns) |
+                           SF_SNAPINVAL, ns);
+               }
                if (expungetype == BLK_NOCOPY || cancelip->i_nlink == 0)
                        dip2->di_mode = 0;
                dip2->di_size = 0;
                dip2->di_blocks = 0;
-               dip2->di_flags =
-                   ufs_rw32(ufs_rw32(dip2->di_flags, ns) & ~SF_SNAPSHOT, ns);
                memset(&dip2->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int64_t));
        }
        bdwrite(bp);
@@ -1441,7 +1460,7 @@
        /*
         * Clear snapshot flag and drop reference.
         */
-       ip->i_flags &= ~SF_SNAPSHOT;
+       ip->i_flags &= ~(SF_SNAPSHOT | SF_SNAPINVAL);
        DIP_ASSIGN(ip, flags, ip->i_flags);
        ip->i_flag |= IN_CHANGE | IN_UPDATE;
 #if defined(QUOTA) || defined(QUOTA2)
@@ -1691,7 +1710,8 @@
                        continue;
                }
                ip = VTOI(vp);
-               if ((ip->i_flags & SF_SNAPSHOT) == 0) {
+               if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) !=
+                   SF_SNAPSHOT) {
                        printf("ffs_snapshot_mount: non-snapshot inode %d\n",
                            fs->fs_snapinum[snaploc]);
                        vput(vp);
diff -r 8103687cd289 -r 4d2c80a753bc sys/ufs/ufs/ufs_bmap.c
--- a/sys/ufs/ufs/ufs_bmap.c    Fri Feb 18 19:05:45 2011 +0000
+++ b/sys/ufs/ufs/ufs_bmap.c    Fri Feb 18 19:54:44 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_bmap.c,v 1.48 2008/03/27 19:06:52 ad Exp $ */
+/*     $NetBSD: ufs_bmap.c,v 1.48.34.1 2011/02/18 19:54:44 bouyer Exp $        */
 
 /*
  * Copyright (c) 1989, 1991, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.48 2008/03/27 19:06:52 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.48.34.1 2011/02/18 19:54:44 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -164,11 +164,13 @@
                 * return a request for a zeroed out buffer if attempts
                 * are made to read a BLK_NOCOPY or BLK_SNAP block.
                 */
-               if ((ip->i_flags & SF_SNAPSHOT) && daddr > 0 &&
+               if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) == SF_SNAPSHOT
+                   && daddr > 0 &&
                    daddr < ump->um_seqinc) {
                        *bnp = -1;
                } else if (*bnp == 0) {
-                       if (ip->i_flags & SF_SNAPSHOT) {
+                       if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL))
+                           == SF_SNAPSHOT) {
                                *bnp = blkptrtodb(ump, bn * ump->um_seqinc);
                        } else {
                                *bnp = -1;
@@ -305,14 +307,15 @@
         * return a request for a zeroed out buffer if attempts are made
         * to read a BLK_NOCOPY or BLK_SNAP block.
         */
-       if ((ip->i_flags & SF_SNAPSHOT) && daddr > 0 &&
-           daddr < ump->um_seqinc) {
+       if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) == SF_SNAPSHOT
+           && daddr > 0 && daddr < ump->um_seqinc) {
                *bnp = -1;
                return (0);
        }
        *bnp = blkptrtodb(ump, daddr);
        if (*bnp == 0) {
-               if (ip->i_flags & SF_SNAPSHOT) {
+               if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL))
+                   == SF_SNAPSHOT) {
                        *bnp = blkptrtodb(ump, bn * ump->um_seqinc);
                } else {
                        *bnp = -1;
diff -r 8103687cd289 -r 4d2c80a753bc sys/ufs/ufs/ufs_readwrite.c
--- a/sys/ufs/ufs/ufs_readwrite.c       Fri Feb 18 19:05:45 2011 +0000
+++ b/sys/ufs/ufs/ufs_readwrite.c       Fri Feb 18 19:54:44 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_readwrite.c,v 1.95 2010/04/23 15:38:46 pooka Exp $ */
+/*     $NetBSD: ufs_readwrite.c,v 1.95.4.1 2011/02/18 19:54:44 bouyer Exp $    */
 
 /*-
  * Copyright (c) 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.95 2010/04/23 15:38:46 pooka Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.95.4.1 2011/02/18 19:54:44 bouyer Exp $");
 
 #ifdef LFS_READWRITE
 #define        FS                      struct lfs
@@ -106,7 +106,7 @@
                return (0);
 
 #ifndef LFS_READWRITE
-       if ((ip->i_flags & SF_SNAPSHOT))
+       if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) == SF_SNAPSHOT)
                return ffs_snapshot_read(vp, uio, ioflag);
 #endif /* !LFS_READWRITE */
 
diff -r 8103687cd289 -r 4d2c80a753bc sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c   Fri Feb 18 19:05:45 2011 +0000
+++ b/sys/ufs/ufs/ufs_vnops.c   Fri Feb 18 19:54:44 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_vnops.c,v 1.186.4.1 2011/01/20 14:25:03 bouyer Exp $       */
+/*     $NetBSD: ufs_vnops.c,v 1.186.4.2 2011/02/18 19:54:44 bouyer Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.186.4.1 2011/01/20 14:25:03 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.186.4.2 2011/02/18 19:54:44 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -482,8 +482,8 @@
                                goto out;
                        }
                        /* Snapshot flag cannot be set or cleared */
-                       if ((vap->va_flags & SF_SNAPSHOT) !=
-                           (ip->i_flags & SF_SNAPSHOT)) {
+                       if ((vap->va_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) !=
+                           (ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL))) {
                                error = EPERM;
                                goto out;
                        }



Home | Main Index | Thread Index | Old Index