Whamcloud - gitweb
LU-1994 kernel: fix reference counting with l_dentry_open
[fs/lustre-release.git] / lustre / obdclass / llog_lvfs.c
index 6046ec5..9373474 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -216,7 +218,7 @@ static int llog_lvfs_write_rec(const struct lu_env *env,
                               struct llog_handle *loghandle,
                               struct llog_rec_hdr *rec,
                               struct llog_cookie *reccookie, int cookiecount,
-                              void *buf, int idx)
+                              void *buf, int idx, struct thandle *th)
 {
         struct llog_log_hdr *llh;
         int reclen = rec->lrh_len, index, rc;
@@ -328,14 +330,14 @@ static int llog_lvfs_write_rec(const struct lu_env *env,
         /*The caller should make sure only 1 process access the lgh_last_idx,
          *Otherwise it might hit the assert.*/
         LASSERT(index < LLOG_BITMAP_SIZE(llh));
-       cfs_spin_lock(&loghandle->lgh_hdr_lock);
+       spin_lock(&loghandle->lgh_hdr_lock);
        if (ext2_set_bit(index, llh->llh_bitmap)) {
                CERROR("argh, index %u already set in log bitmap?\n", index);
-               cfs_spin_unlock(&loghandle->lgh_hdr_lock);
+               spin_unlock(&loghandle->lgh_hdr_lock);
                LBUG(); /* should never happen */
        }
        llh->llh_count++;
-       cfs_spin_unlock(&loghandle->lgh_hdr_lock);
+       spin_unlock(&loghandle->lgh_hdr_lock);
         llh->llh_tail.lrt_index = index;
 
         rc = llog_lvfs_write_blob(obd, file, &llh->llh_hdr, NULL, 0);
@@ -622,9 +624,9 @@ static int llog_lvfs_open(const struct lu_env *env,  struct llog_handle *handle,
                               logid->lgl_ogen, rc);
                        GOTO(out, rc);
                }
-               /* l_dentry_open will call dput(dchild) if there is an error */
                handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild,
                                                 O_RDWR | O_LARGEFILE);
+               l_dput(dchild);
                if (IS_ERR(handle->lgh_file)) {
                        rc = PTR_ERR(handle->lgh_file);
                        handle->lgh_file = NULL;
@@ -634,7 +636,6 @@ static int llog_lvfs_open(const struct lu_env *env,  struct llog_handle *handle,
                               logid->lgl_ogen, rc);
                        GOTO(out, rc);
                }
-
                handle->lgh_id = *logid;
        } else if (name) {
                handle->lgh_file = llog_filp_open(MOUNT_CONFIGS_DIR, name,
@@ -690,6 +691,7 @@ static int llog_lvfs_create(const struct lu_env *env,
        struct llog_ctxt        *ctxt = handle->lgh_ctxt;
        struct obd_device       *obd;
        struct l_dentry         *dchild = NULL;
+       struct file             *file;
        struct obdo             *oa = NULL;
        int                      rc = 0;
        int                      open_flags = O_RDWR | O_CREAT | O_LARGEFILE;
@@ -702,17 +704,16 @@ static int llog_lvfs_create(const struct lu_env *env,
        LASSERT(handle->lgh_file == NULL);
 
        if (handle->lgh_name) {
-               handle->lgh_file = llog_filp_open(MOUNT_CONFIGS_DIR,
-                                                 handle->lgh_name,
-                                                 open_flags, 0644);
-               if (IS_ERR(handle->lgh_file))
-                       RETURN(PTR_ERR(handle->lgh_file));
+               file = llog_filp_open(MOUNT_CONFIGS_DIR, handle->lgh_name,
+                                     open_flags, 0644);
+               if (IS_ERR(file))
+                       RETURN(PTR_ERR(file));
 
                handle->lgh_id.lgl_oseq = FID_SEQ_LLOG;
-               handle->lgh_id.lgl_oid =
-                       handle->lgh_file->f_dentry->d_inode->i_ino;
+               handle->lgh_id.lgl_oid = file->f_dentry->d_inode->i_ino;
                handle->lgh_id.lgl_ogen =
-                       handle->lgh_file->f_dentry->d_inode->i_generation;
+                               file->f_dentry->d_inode->i_generation;
+               handle->lgh_file = file;
        } else {
                OBDO_ALLOC(oa);
                if (oa == NULL)
@@ -734,14 +735,14 @@ static int llog_lvfs_create(const struct lu_env *env,
                if (IS_ERR(dchild))
                        GOTO(out, rc = PTR_ERR(dchild));
 
-               handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild,
-                                                open_flags);
-               if (IS_ERR(handle->lgh_file))
-                       GOTO(out, rc = PTR_ERR(handle->lgh_file));
-
+               file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild, open_flags);
+               l_dput(dchild);
+               if (IS_ERR(file))
+                       GOTO(out, rc = PTR_ERR(file));
                handle->lgh_id.lgl_oseq = oa->o_seq;
                handle->lgh_id.lgl_oid = oa->o_id;
                handle->lgh_id.lgl_ogen = oa->o_generation;
+               handle->lgh_file = file;
 out:
                OBDO_FREE(oa);
        }
@@ -939,6 +940,21 @@ out1:
 }
 EXPORT_SYMBOL(llog_put_cat_list);
 
+static int llog_lvfs_declare_create(const struct lu_env *env,
+                                   struct llog_handle *res,
+                                   struct thandle *th)
+{
+       return 0;
+}
+
+static int llog_lvfs_declare_write_rec(const struct lu_env *env,
+                                      struct llog_handle *loghandle,
+                                      struct llog_rec_hdr *rec,
+                                      int idx, struct thandle *th)
+{
+       return 0;
+}
+
 struct llog_operations llog_lvfs_ops = {
        .lop_write_rec          = llog_lvfs_write_rec,
        .lop_next_block         = llog_lvfs_next_block,
@@ -949,6 +965,8 @@ struct llog_operations llog_lvfs_ops = {
        .lop_close              = llog_lvfs_close,
        .lop_open               = llog_lvfs_open,
        .lop_exist              = llog_lvfs_exist,
+       .lop_declare_create     = llog_lvfs_declare_create,
+       .lop_declare_write_rec  = llog_lvfs_declare_write_rec,
 };
 EXPORT_SYMBOL(llog_lvfs_ops);
 #else /* !__KERNEL__ */