Whamcloud - gitweb
LU-8753 osp: add rpc generation
[fs/lustre-release.git] / lustre / obdclass / llog.c
index f7c398e..7251144 100644 (file)
  *
  * 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
- *
- * 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.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2015, Intel Corporation.
+ * Copyright (c) 2012, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -47,6 +43,7 @@
 
 #define DEBUG_SUBSYSTEM S_LOG
 
+#include <linux/pid_namespace.h>
 #include <linux/kthread.h>
 #include <llog_swab.h>
 #include <lustre_log.h>
@@ -319,7 +316,6 @@ int llog_read_header(const struct lu_env *env, struct llog_handle *handle,
 
                /* lrh_len should be initialized in llog_init_handle */
                handle->lgh_last_idx = 0; /* header is record with index 0 */
-               handle->lgh_write_offset = 0;
                llh->llh_count = 1;         /* for the header record */
                llh->llh_hdr.lrh_type = LLOG_HDR_MAGIC;
                LASSERT(handle->lgh_ctxt->loc_chunk_size >=
@@ -519,8 +515,19 @@ repeat:
                                 * while llog_processing, check this is not
                                 * the case and re-read the current chunk
                                 * otherwise. */
+                               int records;
                                if (index > loghandle->lgh_last_idx)
                                        GOTO(out, rc = 0);
+                               /* <2 records means no more records
+                                * if the last record we processed was
+                                * the final one, then the underlying
+                                * object might have been destroyed yet.
+                                * we better don't access that.. */
+                               mutex_lock(&loghandle->lgh_hdr_mutex);
+                               records = loghandle->lgh_hdr->llh_count;
+                               mutex_unlock(&loghandle->lgh_hdr_mutex);
+                               if (records <= 1)
+                                       GOTO(out, rc = 0);
                                CDEBUG(D_OTHER, "Re-read last llog buffer for "
                                       "new records, index %u, last %u\n",
                                       index, loghandle->lgh_last_idx);
@@ -531,9 +538,13 @@ repeat:
                        }
 
                        if (rec->lrh_len == 0 || rec->lrh_len > chunk_size) {
-                               CWARN("invalid length %d in llog record for "
-                                     "index %d/%d\n", rec->lrh_len,
-                                     rec->lrh_index, index);
+                               CWARN("%s: invalid length %d in llog "DOSTID
+                                     "record for index %d/%d\n",
+                                      loghandle->lgh_ctxt->loc_obd->obd_name,
+                                      rec->lrh_len,
+                                      POSTID(&loghandle->lgh_id.lgl_oi),
+                                      rec->lrh_index, index);
+
                                GOTO(out, rc = -EINVAL);
                        }
 
@@ -544,9 +555,10 @@ repeat:
                        }
 
                        if (rec->lrh_index != index) {
-                               CERROR("%s: Invalid record: index %u but "
-                                      "expected %u\n",
+                               CERROR("%s: "DOSTID" Invalid record: index %u"
+                                      " but expected %u\n",
                                       loghandle->lgh_ctxt->loc_obd->obd_name,
+                                      POSTID(&loghandle->lgh_id.lgl_oi),
                                       rec->lrh_index, index);
                                GOTO(out, rc = -ERANGE);
                        }
@@ -623,6 +635,22 @@ static int llog_process_thread_daemonize(void *arg)
        struct llog_process_info        *lpi = arg;
        struct lu_env                    env;
        int                              rc;
+       struct nsproxy                  *new_ns, *curr_ns = current->nsproxy;
+
+       task_lock(lpi->lpi_reftask);
+       new_ns = lpi->lpi_reftask->nsproxy;
+       if (curr_ns != new_ns) {
+               get_nsproxy(new_ns);
+
+               current->nsproxy = new_ns;
+               /* XXX: we should call put_nsproxy() instead of
+                * atomic_dec(&ns->count) directly. But put_nsproxy() cannot be
+                * used outside of the kernel itself, because it calls
+                * free_nsproxy() which is not exported by the kernel
+                * (defined in kernel/nsproxy.c) */
+               atomic_dec(&curr_ns->count);
+       }
+       task_unlock(lpi->lpi_reftask);
 
        unshare_fs_struct();
 
@@ -649,15 +677,15 @@ int llog_process_or_fork(const struct lu_env *env,
 
         ENTRY;
 
-        OBD_ALLOC_PTR(lpi);
-        if (lpi == NULL) {
-                CERROR("cannot alloc pointer\n");
-                RETURN(-ENOMEM);
-        }
-        lpi->lpi_loghandle = loghandle;
-        lpi->lpi_cb        = cb;
-        lpi->lpi_cbdata    = data;
-        lpi->lpi_catdata   = catdata;
+       OBD_ALLOC_PTR(lpi);
+       if (lpi == NULL) {
+               CERROR("cannot alloc pointer\n");
+               RETURN(-ENOMEM);
+       }
+       lpi->lpi_loghandle = loghandle;
+       lpi->lpi_cb        = cb;
+       lpi->lpi_cbdata    = data;
+       lpi->lpi_catdata   = catdata;
 
        if (fork) {
                struct task_struct *task;
@@ -666,6 +694,10 @@ int llog_process_or_fork(const struct lu_env *env,
                 * init the new one in llog_process_thread_daemonize. */
                lpi->lpi_env = NULL;
                init_completion(&lpi->lpi_completion);
+               /* take reference to current, so that
+                * llog_process_thread_daemonize() can use it to switch to
+                * namespace associated with current  */
+               lpi->lpi_reftask = current;
                task = kthread_run(llog_process_thread_daemonize, lpi,
                                   "llog_process_thread");
                if (IS_ERR(task)) {