summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-01-27 21:48:47 +0000
committerrwatson <rwatson@FreeBSD.org>2009-01-27 21:48:47 +0000
commitc99f201c9eed9159ea6ab00a0bac551174f7e125 (patch)
treecb79a37ed44f348b4bc89493293e632b5eb22f7b /sys/ufs
parent5f74942998479b79250f585067f2adf70b583c5b (diff)
downloadFreeBSD-src-c99f201c9eed9159ea6ab00a0bac551174f7e125.zip
FreeBSD-src-c99f201c9eed9159ea6ab00a0bac551174f7e125.tar.gz
Following a fair amount of real world experience with ACLs and
extended attributes since FreeBSD 5, make the following semantic changes: - Don't update the inode modification time (mtime) when extended attributes (and hence also ACLs) are added, modified, or removed. - Don't update the inode access tie (atime) when extended attributes (and hence also ACLs) are queried. This means that rsync (and related tools) won't improperly think that the data in the file has changed when only the ACL has changed. Note that ffs_reallocblks() has not been changed to not update on an IO_EXT transaction, but currently EAs don't use the cluster write routines so this shouldn't be a problem. If EAs grow support for clustering, then VOP_REALLOCBLKS() will need to grow a flag argument to carry down IO_EXT to UFS. MFC after: 1 week PR: ports/125739 Reported by: Alexander Zagrebin <alexz@visp.ru> Tested by: pluknet <pluknet@gmail.com>, Greg Byshenk <freebsd@byshenk.net> Discussed with: kib, kientzle, timur, Alexander Bokovoy <ab@samba.org>
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c23
-rw-r--r--sys/ufs/ffs/ffs_balloc.c42
-rw-r--r--sys/ufs/ffs/ffs_extern.h6
-rw-r--r--sys/ufs/ffs/ffs_inode.c2
-rw-r--r--sys/ufs/ffs/ffs_vnops.c10
5 files changed, 44 insertions, 39 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index a72137e..e21a484 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -130,10 +130,10 @@ static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *);
* available block is located.
*/
int
-ffs_alloc(ip, lbn, bpref, size, cred, bnp)
+ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp)
struct inode *ip;
ufs2_daddr_t lbn, bpref;
- int size;
+ int size, flags;
struct ucred *cred;
ufs2_daddr_t *bnp;
{
@@ -191,7 +191,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
*bnp = bno;
return (0);
}
@@ -227,12 +230,12 @@ nospace:
* invoked to get an appropriate block.
*/
int
-ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, cred, bpp)
+ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp)
struct inode *ip;
ufs2_daddr_t lbprev;
ufs2_daddr_t bprev;
ufs2_daddr_t bpref;
- int osize, nsize;
+ int osize, nsize, flags;
struct ucred *cred;
struct buf **bpp;
{
@@ -317,7 +320,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
allocbuf(bp, nsize);
bp->b_flags |= B_DONE;
if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)
@@ -392,7 +398,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
allocbuf(bp, nsize);
bp->b_flags |= B_DONE;
if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index 0bd895f..a12f96e 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -133,7 +133,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, nb, dp->di_db[nb],
ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
- &dp->di_db[0]), osize, (int)fs->fs_bsize, cred, &bp);
+ &dp->di_db[0]), osize, (int)fs->fs_bsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -184,7 +185,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
ffs_blkpref_ufs1(ip, lbn, (int)lbn,
- &dp->di_db[0]), osize, nsize, cred, &bp);
+ &dp->di_db[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -200,7 +202,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
- nsize, cred, &newb);
+ nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -241,7 +243,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
- cred, &newb)) != 0) {
+ flags, cred, &newb)) != 0) {
curthread->td_pflags &= saved_inbdflush;
return (error);
}
@@ -291,8 +293,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
if (pref == 0)
pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
- if ((error =
- ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+ if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+ flags, cred, &newb)) != 0) {
brelse(bp);
goto fail;
}
@@ -346,7 +348,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, &bap[0]);
error = ffs_alloc(ip,
- lbn, pref, (int)fs->fs_bsize, cred, &newb);
+ lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
if (error) {
brelse(bp);
goto fail;
@@ -534,7 +536,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
dp->di_extb[nb],
ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
&dp->di_extb[0]), osize,
- (int)fs->fs_bsize, cred, &bp);
+ (int)fs->fs_bsize, flags, cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -545,7 +547,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
dp->di_extsize = smalllblktosize(fs, nb + 1);
dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
bp->b_xflags |= BX_ALTDATA;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
if (flags & IO_SYNC)
bwrite(bp);
else
@@ -588,7 +590,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
error = ffs_realloccg(ip, -1 - lbn,
dp->di_extb[lbn],
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_extb[0]), osize, nsize, cred, &bp);
+ &dp->di_extb[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
bp->b_xflags |= BX_ALTDATA;
@@ -605,7 +608,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
- nsize, cred, &newb);
+ nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, -1 - lbn, nsize, 0, 0, 0);
@@ -618,7 +621,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
nsize, 0, bp);
}
dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
*bpp = bp;
return (0);
}
@@ -636,7 +639,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
error = ffs_realloccg(ip, nb, dp->di_db[nb],
ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
&dp->di_db[0]), osize, (int)fs->fs_bsize,
- cred, &bp);
+ flags, cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -688,7 +691,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_db[0]), osize, nsize, cred, &bp);
+ &dp->di_db[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -704,7 +708,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_db[0]), nsize, cred, &newb);
+ &dp->di_db[0]), nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -745,7 +749,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
- cred, &newb)) != 0) {
+ flags, cred, &newb)) != 0) {
curthread->td_pflags &= saved_inbdflush;
return (error);
}
@@ -795,8 +799,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
if (pref == 0)
pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
- if ((error =
- ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+ if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+ flags, cred, &newb)) != 0) {
brelse(bp);
goto fail;
}
@@ -850,7 +854,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, &bap[0]);
error = ffs_alloc(ip,
- lbn, pref, (int)fs->fs_bsize, cred, &newb);
+ lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
if (error) {
brelse(bp);
goto fail;
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 4a2f3a2..7e32ced 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -48,8 +48,8 @@ struct vnode;
struct vop_fsync_args;
struct vop_reallocblks_args;
-int ffs_alloc(struct inode *,
- ufs2_daddr_t, ufs2_daddr_t, int, struct ucred *, ufs2_daddr_t *);
+int ffs_alloc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, int, int,
+ struct ucred *, ufs2_daddr_t *);
int ffs_balloc_ufs1(struct vnode *a_vp, off_t a_startoffset, int a_size,
struct ucred *a_cred, int a_flags, struct buf **a_bpp);
int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
@@ -72,7 +72,7 @@ void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
int ffs_mountroot(void);
int ffs_reallocblks(struct vop_reallocblks_args *);
int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
- ufs2_daddr_t, int, int, struct ucred *, struct buf **);
+ ufs2_daddr_t, int, int, int, struct ucred *, struct buf **);
int ffs_sbupdate(struct ufsmount *, int, int);
void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_snapblkfree(struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t);
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index e6269b6..b2f9067 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -225,7 +225,7 @@ ffs_truncate(vp, length, flags, cred, td)
oldblks[i] = ip->i_din2->di_extb[i];
ip->i_din2->di_extb[i] = 0;
}
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
if ((error = ffs_update(vp, 1)))
return (error);
for (i = 0; i < NXADDR; i++) {
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index e5b3ffe..ca2efa6 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -1006,14 +1006,6 @@ ffs_extread(struct vnode *vp, struct uio *uio, int ioflag)
bqrelse(bp);
}
}
-
- if ((error == 0 || uio->uio_resid != orig_resid) &&
- (vp->v_mount->mnt_flag & MNT_NOATIME) == 0 &&
- (ip->i_flag & IN_ACCESS) == 0) {
- VI_LOCK(vp);
- ip->i_flag |= IN_ACCESS;
- VI_UNLOCK(vp);
- }
return (error);
}
@@ -1119,7 +1111,7 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred)
bdwrite(bp);
if (error || xfersize == 0)
break;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
}
/*
* If we successfully wrote any data, and we are not the superuser
OpenPOWER on IntegriCloud