extern int zfs_inode_alloc(struct super_block *, struct inode **ip);
extern void zfs_inode_destroy(struct inode *);
extern void zfs_inode_update(znode_t *);
+extern void zfs_mark_inode_dirty(struct inode *);
extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
znode_t *dzp, znode_t *zp, char *name, vsecattr_t *, zfs_fuid_info_t *,
* writepages() normally handles the entire commit for
* performance reasons.
*/
- zil_commit(zsb->z_log, zp->z_id);
+ if (zsb->z_log != NULL)
+ zil_commit(zsb->z_log, zp->z_id);
}
ZFS_EXIT(zsb);
spin_unlock(&ip->i_lock);
}
+/*
+ * Safely mark an inode dirty. Inodes which are part of a read-only
+ * file system or snapshot may not be dirtied.
+ */
+void
+zfs_mark_inode_dirty(struct inode *ip)
+{
+ zfs_sb_t *zsb = ITOZSB(ip);
+
+ if (zfs_is_readonly(zsb) || dmu_objset_is_snapshot(zsb->z_os))
+ return;
+
+ mark_inode_dirty(ip);
+}
+
static uint64_t empty_xattr;
static uint64_t pad[4];
static zfs_acl_phys_t acl_phys;
int error;
if (ITOZ(ip)->z_atime_dirty)
- mark_inode_dirty(ip);
+ zfs_mark_inode_dirty(ip);
crhold(cr);
error = -zfs_close(ip, filp->f_flags, cr);
if (sync_mode != wbc->sync_mode) {
ZFS_ENTER(zsb);
ZFS_VERIFY_ZP(zp);
- zil_commit(zsb->z_log, zp->z_id);
+ if (zsb->z_log != NULL)
+ zil_commit(zsb->z_log, zp->z_id);
ZFS_EXIT(zsb);
/*
if (ip->i_mode != mode) {
ip->i_mode = mode;
ip->i_ctime = current_fs_time(sb);
- mark_inode_dirty(ip);
+ zfs_mark_inode_dirty(ip);
}
if (error == 0)
if (!acl) {
ip->i_mode &= ~current_umask();
ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb);
- mark_inode_dirty(ip);
+ zfs_mark_inode_dirty(ip);
return (0);
}
}
error = __posix_acl_create(&acl, GFP_KERNEL, &mode);
if (error >= 0) {
ip->i_mode = mode;
- mark_inode_dirty(ip);
+ zfs_mark_inode_dirty(ip);
if (error > 0)
error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
}