Illumos #1092: zfs refratio property
[zfs.git] / module / zfs / zfs_vnops.c
index 2139713..262c1ed 100644 (file)
@@ -399,18 +399,14 @@ zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
                return (0);
        }
 
-#ifdef HAVE_MANDLOCKS
        /*
         * Check for mandatory locks
         */
-       if (MANDMODE(zp->z_mode)) {
-               if (error = chklock(ip, FREAD,
-                   uio->uio_loffset, uio->uio_resid, uio->uio_fmode, ct)) {
-                       ZFS_EXIT(zsb);
-                       return (error);
-               }
+       if (mandatory_lock(ip) &&
+           !lock_may_read(ip, uio->uio_loffset, uio->uio_resid)) {
+               ZFS_EXIT(zsb);
+               return (EAGAIN);
        }
-#endif /* HAVE_MANDLOCK */
 
        /*
         * If we're in FRSYNC mode, sync out this znode before reading it.
@@ -581,17 +577,14 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
                return (EINVAL);
        }
 
-#ifdef HAVE_MANDLOCKS
        /*
         * Check for mandatory locks before calling zfs_range_lock()
         * in order to prevent a deadlock with locks set via fcntl().
         */
-       if (MANDMODE((mode_t)zp->z_mode) &&
-           (error = chklock(ip, FWRITE, woff, n, uio->uio_fmode, ct)) != 0) {
+       if (mandatory_lock(ip) && !lock_may_write(ip, woff, n)) {
                ZFS_EXIT(zsb);
-               return (error);
+               return (EAGAIN);
        }
-#endif /* HAVE_MANDLOCKS */
 
 #ifdef HAVE_UIO_ZEROCOPY
        /*
@@ -1120,14 +1113,6 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
 
        if (flags & LOOKUP_XATTR) {
                /*
-                * If the xattr property is off, refuse the lookup request.
-                */
-               if (!(zsb->z_flags & ZSB_XATTR_USER)) {
-                       ZFS_EXIT(zsb);
-                       return (EINVAL);
-               }
-
-               /*
                 * We don't allow recursive attributes..
                 * Maybe someday we will.
                 */
@@ -2298,6 +2283,44 @@ zfs_getattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
 EXPORT_SYMBOL(zfs_getattr);
 
 /*
+ * Get the basic file attributes and place them in the provided kstat
+ * structure.  The inode is assumed to be the authoritative source
+ * for most of the attributes.  However, the znode currently has the
+ * authoritative atime, blksize, and block count.
+ *
+ *     IN:     ip      - inode of file.
+ *
+ *     OUT:    sp      - kstat values.
+ *
+ *     RETURN: 0 (always succeeds)
+ */
+/* ARGSUSED */
+int
+zfs_getattr_fast(struct inode *ip, struct kstat *sp)
+{
+       znode_t *zp = ITOZ(ip);
+       zfs_sb_t *zsb = ITOZSB(ip);
+
+       mutex_enter(&zp->z_lock);
+
+       generic_fillattr(ip, sp);
+       ZFS_TIME_DECODE(&sp->atime, zp->z_atime);
+
+       sa_object_size(zp->z_sa_hdl, (uint32_t *)&sp->blksize, &sp->blocks);
+       if (unlikely(zp->z_blksz == 0)) {
+               /*
+                * Block size hasn't been set; suggest maximal I/O transfers.
+                */
+               sp->blksize = zsb->z_max_blksz;
+       }
+
+       mutex_exit(&zp->z_lock);
+
+       return (0);
+}
+EXPORT_SYMBOL(zfs_getattr_fast);
+
+/*
  * Set the file attributes to the values contained in the
  * vattr structure.
  *
@@ -2420,7 +2443,7 @@ top:
        aclp = NULL;
 
        /* Can this be moved to before the top label? */
-       if (zsb->z_vfs->mnt_flags & MNT_READONLY) {
+       if (zfs_is_readonly(zsb)) {
                err = EROFS;
                goto out3;
        }
@@ -3815,7 +3838,6 @@ zfs_putpage(struct page *page, struct writeback_control *wbc, void *data)
        struct inode         *ip      = mapping->host;
        znode_t              *zp      = ITOZ(ip);
        zfs_sb_t             *zsb     = ITOZSB(ip);
-       rl_t                 *rl;
        u_offset_t           io_off;
        size_t               io_len;
        size_t               len;
@@ -3827,11 +3849,8 @@ zfs_putpage(struct page *page, struct writeback_control *wbc, void *data)
        ZFS_ENTER(zsb);
        ZFS_VERIFY_ZP(zp);
 
-       rl = zfs_range_lock(zp, io_off, io_len, RL_WRITER);
-
        if (io_off > zp->z_size) {
                /* past end of file */
-               zfs_range_unlock(rl);
                ZFS_EXIT(zsb);
                return (0);
        }
@@ -3839,7 +3858,6 @@ zfs_putpage(struct page *page, struct writeback_control *wbc, void *data)
        len = MIN(io_len, P2ROUNDUP(zp->z_size, PAGESIZE) - io_off);
 
        error = zfs_putapage(ip, page, io_off, len);
-       zfs_range_unlock(rl);
 
        if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
                zil_commit(zsb->z_log, zp->z_id);