Linux 2.6.29 compat, credentials
[zfs.git] / module / zfs / zfs_vnops.c
index 29ddaf0..00534d8 100644 (file)
  *     return (error);                 // done, report error
  */
 
+/*
+ * Virus scanning is unsupported.  It would be possible to add a hook
+ * here to performance the required virus scan.  This could be done
+ * entirely in the kernel or potentially as an update to invoke a
+ * scanning utility.
+ */
+static int
+zfs_vscan(struct inode *ip, cred_t *cr, int async)
+{
+       return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
+{
+       znode_t *zp = ITOZ(ip);
+       zfs_sb_t *zsb = ITOZSB(ip);
+
+       ZFS_ENTER(zsb);
+       ZFS_VERIFY_ZP(zp);
+
+       /* Honor ZFS_APPENDONLY file attribute */
+       if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) &&
+           ((flag & O_APPEND) == 0)) {
+               ZFS_EXIT(zsb);
+               return (EPERM);
+       }
+
+       /* Virus scan eligible files on open */
+       if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
+           !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) {
+               if (zfs_vscan(ip, cr, 0) != 0) {
+                       ZFS_EXIT(zsb);
+                       return (EACCES);
+               }
+       }
+
+       /* Keep a count of the synchronous opens in the znode */
+       if (flag & O_SYNC)
+               atomic_inc_32(&zp->z_sync_cnt);
+
+       ZFS_EXIT(zsb);
+       return (0);
+}
+EXPORT_SYMBOL(zfs_open);
+
+/* ARGSUSED */
+int
+zfs_close(struct inode *ip, int flag, cred_t *cr)
+{
+       znode_t *zp = ITOZ(ip);
+       zfs_sb_t *zsb = ITOZSB(ip);
+
+       ZFS_ENTER(zsb);
+       ZFS_VERIFY_ZP(zp);
+
+       /* Decrement the synchronous opens in the znode */
+       if (flag & O_SYNC)
+               zp->z_sync_cnt = 0;
+
+       if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
+           !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0)
+               VERIFY(zfs_vscan(ip, cr, 1) == 0);
+
+       ZFS_EXIT(zsb);
+       return (0);
+}
+EXPORT_SYMBOL(zfs_close);
+
 #if defined(_KERNEL)
 /*
  * When a file is memory mapped, we must keep the IO data synchronized
@@ -2265,7 +2335,7 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
        zfs_acl_t       *aclp;
        boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
        boolean_t       fuid_dirtied = B_FALSE;
-       sa_bulk_attr_t  bulk[7], xattr_bulk[7];
+       sa_bulk_attr_t  *bulk, *xattr_bulk;
        int             count = 0, xattr_count = 0;
 
        if (mask == 0)
@@ -2308,6 +2378,9 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
        tmpxvattr = kmem_alloc(sizeof(xvattr_t), KM_SLEEP);
        xva_init(tmpxvattr);
 
+       bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 7, KM_SLEEP);
+       xattr_bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 7, KM_SLEEP);
+
        /*
         * Immutable files can only alter immutable bit and atime
         */
@@ -2848,6 +2921,8 @@ out2:
                zil_commit(zilog, 0);
 
 out3:
+       kmem_free(xattr_bulk, sizeof(sa_bulk_attr_t) * 7);
+       kmem_free(bulk, sizeof(sa_bulk_attr_t) * 7);
        kmem_free(tmpxvattr, sizeof(xvattr_t));
        ZFS_EXIT(zsb);
        return (err);