Whamcloud - gitweb
Land b1_8_gate onto b1_8 (20081218_1708)
[fs/lustre-release.git] / lustre / liblustre / file.c
index bd67c0f..accc378 100644 (file)
@@ -1,24 +1,41 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Lustre Light file operations
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
  *
- *  Copyright (c) 2002-2004 Cluster File Systems, Inc.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
  *
- *   This file is part of Lustre, http://www.lustre.org.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
  *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
+ * lustre/liblustre/file.c
  *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Lustre Light file operations
  */
 
 #define DEBUG_SUBSYSTEM S_LLITE
@@ -82,14 +99,14 @@ void llu_prepare_mdc_op_data(struct mdc_op_data *data,
 
         if (i1) {
                 ll_i2gids(data->suppgids, i1, i2);
-                ll_inode2fid(&data->fid1, i1);
+                llu_inode2fid(&data->fid1, i1);
         }else {
                 ll_i2gids(data->suppgids, i2, i1);
-                ll_inode2fid(&data->fid1, i2);
+                llu_inode2fid(&data->fid1, i2);
         }
 
         if (i2)
-                ll_inode2fid(&data->fid2, i2);
+                llu_inode2fid(&data->fid2, i2);
         else
                 memset(&data->fid2, 0, sizeof(data->fid2));
 
@@ -115,16 +132,10 @@ void obdo_refresh_inode(struct inode *dst,
 
         if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(st->st_atime))
                 LTIME_S(st->st_atime) = src->o_atime;
-        
-        /* mtime is always updated with ctime, but can be set in past.
-           As write and utime(2) may happen within 1 second, and utime's
-           mtime has a priority over write's one, leave mtime from mds 
-           for the same ctimes. */
-        if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(st->st_ctime)) {
+        if (valid & OBD_MD_FLMTIME && src->o_mtime > LTIME_S(st->st_mtime))
+                LTIME_S(st->st_mtime) = src->o_mtime;
+        if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(st->st_ctime))
                 LTIME_S(st->st_ctime) = src->o_ctime;
-                if (valid & OBD_MD_FLMTIME)
-                        LTIME_S(st->st_mtime) = src->o_mtime;
-        }
         if (valid & OBD_MD_FLSIZE && src->o_size > st->st_size)
                 st->st_size = src->o_size;
         /* optimum IO size */
@@ -319,6 +330,7 @@ int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode)
         struct ptlrpc_request *req = NULL;
         struct obd_client_handle *och = &fd->fd_mds_och;
         struct obdo obdo;
+        struct mdc_op_data data = { { 0 } };
         int rc, valid;
         ENTRY;
 
@@ -343,7 +355,8 @@ int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode)
                 obdo.o_flags = MDS_BFLAG_UNCOMMITTED_WRITES;
                 obdo.o_valid |= OBD_MD_FLFLAGS;
         }
-        rc = mdc_close(mdc_exp, &obdo, och, &req);
+        data.fid1 = lli->lli_fid;
+        rc = mdc_close(mdc_exp, &data, &obdo, och, &req);
         if (rc == EAGAIN) {
                 /* We are the last writer, so the MDS has instructed us to get
                  * the file size and any write cookies, then close again. */
@@ -461,6 +474,7 @@ static void llu_truncate(struct inode *inode, obd_flag flags)
         struct intnl_stat *st = llu_i2stat(inode);
         struct obd_info oinfo = { { { 0 } } };
         struct obdo oa = { 0 };
+        obd_valid valid;
         int rc;
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu/%lu(%p) to %llu\n",
@@ -482,9 +496,41 @@ static void llu_truncate(struct inode *inode, obd_flag flags)
         oa.o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS;
         oa.o_flags = flags; /* We don't actually want to copy inode flags */
  
-        obdo_from_inode(&oa, inode,
-                        OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLATIME |
-                        OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+        valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLATIME;
+        if (flags & OBD_FL_TRUNCLOCK) {
+                /* lockless truncate
+                 *
+                 * 1. do not use inode's timestamps because concurrent
+                 * stat might fill the inode with out-of-date times,
+                 * send current instead
+                 *
+                 * 2.do no update lsm, as long as stat (via
+                 * llu_glimpse_size) will bring attributes from osts
+                 * anyway */
+                oa.o_mtime = oa.o_ctime = CURRENT_TIME;
+                oa.o_valid |= OBD_MD_FLMTIME | OBD_MD_FLCTIME;
+        } else {
+                /* truncate under locks
+                 *
+                 * 1. update inode's mtime and ctime as long as
+                 * concurrent stat (via llu_glimpse_size) might bring
+                 * out-of-date ones
+                 *
+                 * 2. update lsm so that next stat (via
+                 * llu_glimpse_size) could get correct values in lsm */
+                struct ost_lvb xtimes;
+
+                lov_stripe_lock(lli->lli_smd);
+                st->st_mtime = st->st_ctime = CURRENT_TIME;
+                xtimes.lvb_mtime = st->st_mtime;
+                xtimes.lvb_ctime = st->st_ctime;
+                obd_update_lvb(llu_i2obdexp(inode), lli->lli_smd, &xtimes,
+                               OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+                lov_stripe_unlock(lli->lli_smd);
+
+                valid |= OBD_MD_FLMTIME | OBD_MD_FLCTIME;
+        }
+        obdo_from_inode(&oa, inode, valid);
 
         obd_adjust_kms(llu_i2obdexp(inode), lli->lli_smd, st->st_size, 1);