Whamcloud - gitweb
LU-827 lov: Implement a per file data_version.
[fs/lustre-release.git] / lustre / llite / file.c
index 231f2f3..80dcdb8 100644 (file)
@@ -708,7 +708,8 @@ static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp,
                                OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
                                OBD_MD_FLBLKSZ | OBD_MD_FLATIME |
                                OBD_MD_FLMTIME | OBD_MD_FLCTIME |
-                               OBD_MD_FLGROUP | OBD_MD_FLEPOCH;
+                               OBD_MD_FLGROUP | OBD_MD_FLEPOCH |
+                               OBD_MD_FLDATAVERSION;
         oinfo.oi_capa = capa;
         if (sync) {
                 oinfo.oi_oa->o_valid |= OBD_MD_FLFLAGS;
@@ -728,7 +729,8 @@ static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp,
         if (rc == 0)
                 oinfo.oi_oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
                                          OBD_MD_FLATIME | OBD_MD_FLMTIME |
-                                         OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+                                         OBD_MD_FLCTIME | OBD_MD_FLSIZE |
+                                         OBD_MD_FLDATAVERSION);
         RETURN(rc);
 }
 
@@ -1746,6 +1748,48 @@ error:
         RETURN(rc);
 }
 
+/*
+ * Read the data_version for inode.
+ *
+ * This value is computed using stripe object version on OST.
+ * Version is computed using server side locking.
+ *
+ * @param extent_lock  Take extent lock. Not needed if a process is already
+ *                     holding the OST object group locks.
+ */
+static int ll_data_version(struct inode *inode, __u64 *data_version,
+                           int extent_lock)
+{
+        struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
+        struct ll_sb_info    *sbi = ll_i2sbi(inode);
+        struct obdo          *obdo = NULL;
+        int                   rc;
+        ENTRY;
+
+        /* If no stripe, we consider version is 0. */
+        if (!lsm) {
+                *data_version = 0;
+                CDEBUG(D_INODE, "No object for inode\n");
+                RETURN(0);
+        }
+
+        OBD_ALLOC_PTR(obdo);
+        if (obdo == NULL)
+                RETURN(-ENOMEM);
+
+        rc = ll_lsm_getattr(lsm, sbi->ll_dt_exp, NULL, obdo, 0, extent_lock);
+        if (!rc) {
+                if (!(obdo->o_valid & OBD_MD_FLDATAVERSION))
+                        rc = -EOPNOTSUPP;
+                else
+                        *data_version = obdo->o_data_version;
+        }
+
+        OBD_FREE_PTR(obdo);
+
+        RETURN(rc);
+}
+
 #ifdef HAVE_UNLOCKED_IOCTL
 long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
@@ -1836,6 +1880,23 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
         }
         case OBD_IOC_FID2PATH:
                 RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
+        case LL_IOC_DATA_VERSION: {
+                struct ioc_data_version idv;
+                int rc;
+
+                if (cfs_copy_from_user(&idv, (char *)arg, sizeof(idv)))
+                        RETURN(-EFAULT);
+
+                rc = ll_data_version(inode, &idv.idv_version,
+                                     !(idv.idv_flags & LL_DV_NOFLUSH));
+
+                if (rc == 0 &&
+                    cfs_copy_to_user((char *) arg, &idv, sizeof(idv)))
+                        RETURN(-EFAULT);
+
+                RETURN(rc);
+        }
+
         case LL_IOC_GET_MDTIDX: {
                 int mdtidx;