Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libperfuse Fix memory leak when we discard a voided seta...
details: https://anonhg.NetBSD.org/src/rev/05a0ac2b242f
branches: trunk
changeset: 779733:05a0ac2b242f
user: manu <manu%NetBSD.org@localhost>
date: Thu Jun 14 05:58:22 2012 +0000
description:
Fix memory leak when we discard a voided setattr operation
diffstat:
lib/libperfuse/ops.c | 161 +++++++++++++++++++++++++++-----------------------
1 files changed, 86 insertions(+), 75 deletions(-)
diffs (236 lines):
diff -r a22a9b612922 -r 05a0ac2b242f lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c Thu Jun 14 05:14:41 2012 +0000
+++ b/lib/libperfuse/ops.c Thu Jun 14 05:58:22 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ops.c,v 1.56 2012/06/13 01:45:56 manu Exp $ */
+/* $NetBSD: ops.c,v 1.57 2012/06/14 05:58:22 manu Exp $ */
/*-
* Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -1696,6 +1696,7 @@
struct fuse_attr_out *fao;
struct vattr *old_va;
int error;
+ int valid;
#ifdef PERFUSE_DEBUG
struct vattr *old_vap;
int resize_debug = 0;
@@ -1719,39 +1720,94 @@
}
old_va = puffs_pn_getvap((struct puffs_node *)opc);
+ valid = 0;
/*
* Check for permission to change size
*/
- if ((vap->va_size != (u_quad_t)PUFFS_VNOVAL) &&
- (error = mode_access(opc, pcr, PUFFS_VWRITE)) != 0)
- return error;
+ if ((vap->va_size != (u_quad_t)PUFFS_VNOVAL)) {
+ if ((error = mode_access(opc, pcr, PUFFS_VWRITE)) != 0)
+ return error;
+ valid |= FUSE_FATTR_SIZE;
+ }
+
+ /*
+ * Check for permission to change owner and group
+ */
+ if ((vap->va_uid != (uid_t)PUFFS_VNOVAL) ||
+ (vap->va_gid != (gid_t)PUFFS_VNOVAL)) {
+ if (puffs_access_chown(old_va->va_uid, old_va->va_gid,
+ vap->va_uid, vap->va_gid, pcr) != 0)
+ return EACCES;
+
+ if (vap->va_uid != (uid_t)PUFFS_VNOVAL)
+ valid |= FUSE_FATTR_UID;
+
+ if (vap->va_gid != (uid_t)PUFFS_VNOVAL)
+ valid |= FUSE_FATTR_GID;
+ }
+
+ /*
+ * Check for permission to change permissions
+ */
+ if (vap->va_mode != (mode_t)PUFFS_VNOVAL) {
+ if (puffs_access_chmod(old_va->va_uid, old_va->va_gid,
+ old_va->va_type, vap->va_mode, pcr) != 0)
+ return EACCES;
+ valid |= FUSE_FATTR_MODE;
+ }
/*
* Check for permission to change dates
*/
- if (((vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL) ||
- (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)) &&
- (puffs_access_times(old_va->va_uid, old_va->va_gid,
- old_va->va_mode, 0, pcr) != 0))
- return EACCES;
+ if ((vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL) ||
+ (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)) {
+ if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL)
+ valid |= FUSE_FATTR_ATIME;
+
+ if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)
+ valid |= FUSE_FATTR_MTIME;
+
+ /*
+ * ftruncate() sends only va_size, and metadata cache
+ * flush adds va_atime and va_mtime. Some FUSE
+ * filesystems will attempt to detect ftruncate by
+ * checking for FATTR_SIZE being set without
+ * FATTR_UID|FATTR_GID|FATTR_ATIME|FATTR_MTIME|FATTR_MODE
+ *
+ * Try to adapt and remove FATTR_ATIME|FATTR_MTIME
+ * if we suspect a ftruncate().
+ */
+ if ((valid & FUSE_FATTR_SIZE) &&
+ !(valid & (FUSE_FATTR_UID|FUSE_FATTR_GID|FUSE_FATTR_MODE)))
+ valid &= ~(FUSE_FATTR_ATIME|FUSE_FATTR_MTIME);
+
+ /*
+ * There is the same mess with fchmod()
+ */
+ if ((valid & FUSE_FATTR_MODE) &&
+ !(valid & (FUSE_FATTR_UID|FUSE_FATTR_GID)))
+ valid &= ~(FUSE_FATTR_ATIME|FUSE_FATTR_MTIME);
+
+ /*
+ * And if a change on atime/mtime remains, check permissions.
+ */
+ if ((valid & (FUSE_FATTR_ATIME|FUSE_FATTR_MTIME)) &&
+ (puffs_access_times(old_va->va_uid, old_va->va_gid,
+ old_va->va_mode, 0, pcr) != 0))
+ return EACCES;
+ }
/*
- * Check for permission to change owner and group
+ * If nothing remain, discard the operation. This happend when
+ * only ctime is changed.
*/
- if (((vap->va_uid != (uid_t)PUFFS_VNOVAL) ||
- (vap->va_gid != (gid_t)PUFFS_VNOVAL)) &&
- (puffs_access_chown(old_va->va_uid, old_va->va_gid,
- vap->va_uid, vap->va_gid, pcr)) != 0)
- return EACCES;
-
- /*
- * Check for permission to change permissions
- */
- if ((vap->va_mode != (mode_t)PUFFS_VNOVAL) &&
- (puffs_access_chmod(old_va->va_uid, old_va->va_gid,
- old_va->va_type, vap->va_mode, pcr)) != 0)
- return EACCES;
+ if (!(valid & (FUSE_FATTR_SIZE|FUSE_FATTR_ATIME|FUSE_FATTR_MTIME|
+ FUSE_FATTR_MODE|FUSE_FATTR_UID|FUSE_FATTR_GID))) {
+ error = 0;
+ goto out;
+ }
+
pm = ps->ps_new_msg(pu, opc, FUSE_SETATTR, sizeof(*fsi), pcr);
fsi = GET_INPAYLOAD(ps, pm, fuse_setattr_in);
@@ -1766,7 +1822,7 @@
fsi->valid |= FUSE_FATTR_FH;
}
- if (vap->va_size != (u_quad_t)PUFFS_VNOVAL) {
+ if (valid & FUSE_FATTR_SIZE) {
fsi->size = vap->va_size;
fsi->valid |= FUSE_FATTR_SIZE;
@@ -1787,10 +1843,8 @@
* dates being reset to Epoch on glusterfs. If one
* is missing, use the old value.
*/
- if ((vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) ||
- (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL)) {
-
- if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL) {
+ if (valid & (FUSE_FATTR_ATIME|FUSE_FATTR_MTIME)) {
+ if (valid & FUSE_FATTR_ATIME) {
fsi->atime = vap->va_atime.tv_sec;
fsi->atimensec = (uint32_t)vap->va_atime.tv_nsec;
} else {
@@ -1798,7 +1852,7 @@
fsi->atimensec = (uint32_t)old_va->va_atime.tv_nsec;
}
- if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) {
+ if (valid & FUSE_FATTR_MTIME) {
fsi->mtime = vap->va_mtime.tv_sec;
fsi->mtimensec = (uint32_t)vap->va_mtime.tv_nsec;
} else {
@@ -1809,17 +1863,17 @@
fsi->valid |= (FUSE_FATTR_MTIME|FUSE_FATTR_ATIME);
}
- if (vap->va_mode != (mode_t)PUFFS_VNOVAL) {
+ if (valid & FUSE_FATTR_MODE) {
fsi->mode = vap->va_mode;
fsi->valid |= FUSE_FATTR_MODE;
}
- if (vap->va_uid != (uid_t)PUFFS_VNOVAL) {
+ if (valid & FUSE_FATTR_UID) {
fsi->uid = vap->va_uid;
fsi->valid |= FUSE_FATTR_UID;
}
- if (vap->va_gid != (gid_t)PUFFS_VNOVAL) {
+ if (valid & FUSE_FATTR_GID) {
fsi->gid = vap->va_gid;
fsi->valid |= FUSE_FATTR_GID;
}
@@ -1829,49 +1883,6 @@
fsi->valid |= FUSE_FATTR_LOCKOWNER;
}
- /*
- * ftruncate() sends only va_size, and metadata cache
- * flush adds va_atime and va_mtime. Some FUSE
- * filesystems will attempt to detect ftruncate by
- * checking for FATTR_SIZE being set without
- * FATTR_UID|FATTR_GID|FATTR_ATIME|FATTR_MTIME|FATTR_MODE
- *
- * Try to adapt and remove FATTR_ATIME|FATTR_MTIME
- * if we suspect a ftruncate().
- */
- if ((vap->va_size != (u_quad_t)PUFFS_VNOVAL) &&
- ((vap->va_mode == (mode_t)PUFFS_VNOVAL) &&
- (vap->va_uid == (uid_t)PUFFS_VNOVAL) &&
- (vap->va_gid == (gid_t)PUFFS_VNOVAL))) {
- fsi->atime = 0;
- fsi->atimensec = 0;
- fsi->mtime = 0;
- fsi->mtimensec = 0;
- fsi->valid &= ~(FUSE_FATTR_ATIME|FUSE_FATTR_MTIME);
- }
-
- /*
- * There is the same mess with fchmod()
- */
- if ((vap->va_mode != (mode_t)PUFFS_VNOVAL) &&
- (vap->va_uid == (uid_t)PUFFS_VNOVAL) &&
- (vap->va_gid == (gid_t)PUFFS_VNOVAL)) {
- fsi->atime = 0;
- fsi->atimensec = 0;
- fsi->mtime = 0;
- fsi->mtimensec = 0;
- fsi->valid &= ~(FUSE_FATTR_ATIME|FUSE_FATTR_MTIME);
- }
-
- /*
- * If nothing remain, discard the operation.
- */
- if (!(fsi->valid & (FUSE_FATTR_SIZE|FUSE_FATTR_ATIME|FUSE_FATTR_MTIME|
- FUSE_FATTR_MODE|FUSE_FATTR_UID|FUSE_FATTR_GID))) {
- ps->ps_destroy_msg(pm);
- error = 0;
- goto out;
- }
#ifdef PERFUSE_DEBUG
old_vap = puffs_pn_getvap((struct puffs_node *)opc);
Home |
Main Index |
Thread Index |
Old Index