Whamcloud - gitweb
Revert "LU-2800 autoconf: remove LC_PROCFS_USERS test" 83/7083/2
authorOleg Drokin <oleg.drokin@intel.com>
Tue, 23 Jul 2013 06:00:09 +0000 (06:00 +0000)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 23 Jul 2013 06:00:19 +0000 (06:00 +0000)
Unfortunately this now breaks build due to a new user of the function emerged.

This reverts commit 663ef6abd788c3388cae8d5bc5421bad99979c8b

Change-Id: If69fe87cea77c83ae815a1125f2cdbce0caaa1db
Reviewed-on: http://review.whamcloud.com/7083
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Tested-by: Oleg Drokin <oleg.drokin@intel.com>
libcfs/include/libcfs/params_tree.h
lustre/autoconf/lustre-core.m4
lustre/fld/lproc_fld.c
lustre/include/lprocfs_status.h
lustre/lod/lproc_lod.c
lustre/lov/lproc_lov.c
lustre/mdt/mdt_hsm_cdt_actions.c
lustre/obdclass/lprocfs_jobstats.c
lustre/obdclass/lprocfs_status.c
lustre/ptlrpc/lproc_ptlrpc.c
lustre/quota/lproc_quota.c

index 41413eb..1bf8d37 100644 (file)
@@ -78,8 +78,46 @@ typedef struct poll_table_struct                cfs_poll_table_t;
 /* in lprocfs_stat.c, to protect the private data for proc entries */
 extern struct rw_semaphore             _lprocfs_lock;
 
+/* to begin from 2.6.23, Linux defines self file_operations (proc_reg_file_ops)
+ * in procfs, the proc file_operation defined by Lustre (lprocfs_generic_fops)
+ * will be wrapped into the new defined proc_reg_file_ops, which instroduces
+ * user count in proc_dir_entrey(pde_users) to protect the proc entry from
+ * being deleted. then the protection lock (_lprocfs_lock) defined by Lustre
+ * isn't necessary anymore for lprocfs_generic_fops(e.g. lprocfs_fops_read).
+ * see bug19706 for detailed information.
+ */
+#ifndef HAVE_PROCFS_USERS
+
+#define LPROCFS_ENTRY()                \
+do {                                   \
+       down_read(&_lprocfs_lock);      \
+} while(0)
+
+#define LPROCFS_EXIT()                 \
+do {                                   \
+       up_read(&_lprocfs_lock);        \
+} while(0)
+
+#else
+#define LPROCFS_ENTRY() do{ }while(0)
+#define LPROCFS_EXIT()  do{ }while(0)
+#endif
+
+#ifdef HAVE_PROCFS_DELETED
+
+static inline
+int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
+{
+        LPROCFS_ENTRY();
+        if ((dp)->deleted) {
+                LPROCFS_EXIT();
+                return -ENODEV;
+        }
+        return 0;
+}
+#elif defined(HAVE_PROCFS_USERS) /* !HAVE_PROCFS_DELETED*/
 static inline
-int LPROCFS_ENTRY_CHECK(struct proc_dir_entry *dp)
+int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
 {
        int deleted = 0;
 
@@ -91,6 +129,14 @@ int LPROCFS_ENTRY_CHECK(struct proc_dir_entry *dp)
                return -ENODEV;
        return 0;
 }
+#else /* !HAVE_PROCFS_DELETED*/
+static inline
+int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
+{
+        LPROCFS_ENTRY();
+        return 0;
+}
+#endif /* HAVE_PROCFS_DELETED */
 #define LPROCFS_SRCH_ENTRY()            \
 do {                                    \
         down_read(&_lprocfs_lock);      \
@@ -201,9 +247,12 @@ do {                                                    \
         rc = 0;                                         \
 } while(0)
 
+#define LPROCFS_ENTRY()             do {} while(0)
+#define LPROCFS_EXIT()              do {} while(0)
 static inline
-int LPROCFS_ENTRY_CHECK(cfs_param_dentry_t *dp)
+int LPROCFS_ENTRY_AND_CHECK(cfs_param_dentry_t *dp)
 {
+        LPROCFS_ENTRY();
         return 0;
 }
 #define LPROCFS_WRITE_ENTRY()       do {} while(0)
index cd6fd43..ec50de0 100644 (file)
@@ -461,6 +461,36 @@ LB_LINUX_TRY_COMPILE([
 ])
 ])
 
+# 2.6.23 add code to wait other users to complete before removing procfs entry
+AC_DEFUN([LC_PROCFS_USERS],
+[AC_MSG_CHECKING([if kernel has pde_users member in procfs entry struct])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/proc_fs.h>
+],[
+        struct proc_dir_entry pde;
+
+        pde.pde_users   = 0;
+],[
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_PROCFS_USERS, 1,
+                [kernel has pde_users member in procfs entry struct])
+],[
+       LB_LINUX_TRY_COMPILE([
+               #include "$LINUX/fs/proc/internal.h"
+       ],[
+               struct proc_dir_entry_aux pde_aux;
+
+               pde_aux.pde_users = 0;
+       ],[
+               AC_MSG_RESULT([yes])
+               AC_DEFINE(HAVE_PROCFS_USERS, 1,
+                       [kernel has pde_users member in proc_dir_entry_aux])
+       ],[
+               AC_MSG_RESULT([no])
+       ])
+])
+])
+
 # 2.6.24
 
 # 2.6.24 has bio_endio with 2 args
@@ -479,6 +509,24 @@ LB_LINUX_TRY_COMPILE([
 ])
 ])
 
+# 2.6.24 removes long aged procfs entry -> deleted member
+AC_DEFUN([LC_PROCFS_DELETED],
+[AC_MSG_CHECKING([if kernel has deleted member in procfs entry struct])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/proc_fs.h>
+],[
+        struct proc_dir_entry pde;
+
+        pde.deleted = sizeof(pde);
+], [
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_PROCFS_DELETED, 1,
+                [kernel has deleted member in procfs entry struct])
+],[
+        AC_MSG_RESULT([no])
+])
+])
+
 # 2.6.26
 
 # 2.6.26 isn't export set_fs_pwd and change paramter in fs struct
@@ -1516,9 +1564,11 @@ AC_DEFUN([LC_PROG_LINUX],
 
          # 2.6.23
          LC_UNREGISTER_BLKDEV_RETURN_INT
+         LC_PROCFS_USERS
 
          # 2.6.24
          LC_BIO_ENDIO_2ARG
+         LC_PROCFS_DELETED
 
          # 2.6.26
          LC_FS_STRUCT_USE_PATH
index c3734c7..97bd3d5 100644 (file)
@@ -282,7 +282,7 @@ static int fldb_seq_open(struct inode *inode, struct file *file)
        int                     env_init = 0;
        int                     rc;
 
-       LPROCFS_ENTRY_CHECK(dp);
+       LPROCFS_ENTRY_AND_CHECK(dp);
        rc = seq_open(file, &fldb_sops);
        if (rc)
                GOTO(out, rc);
@@ -319,6 +319,7 @@ out:
                        lu_env_fini(&param->fsp_env);
                if (param != NULL)
                        OBD_FREE_PTR(param);
+               LPROCFS_EXIT();
        }
        return rc;
 }
index 9142ac9..ff60773 100644 (file)
@@ -750,8 +750,14 @@ extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
 #define __LPROC_SEQ_FOPS(name, custom_seq_write)                           \
 static int name##_single_open(cfs_inode_t *inode, struct file *file) {     \
         struct proc_dir_entry *dp = PDE(inode);                            \
-       LPROCFS_ENTRY_CHECK(dp);                                           \
-       return single_open(file, name##_seq_show, dp->data);               \
+        int rc;                                                            \
+        LPROCFS_ENTRY_AND_CHECK(dp);                                       \
+        rc = single_open(file, name##_seq_show, dp->data);                 \
+        if (rc) {                                                          \
+                LPROCFS_EXIT();                                            \
+                return rc;                                                 \
+        }                                                                  \
+        return 0;                                                          \
 }                                                                          \
 struct file_operations name##_fops = {                                     \
         .owner   = THIS_MODULE,                                            \
index e976063..6fe74e3 100644 (file)
@@ -418,10 +418,12 @@ static int lod_osts_seq_open(struct inode *inode, struct file *file)
        struct seq_file *seq;
        int rc;
 
-       LPROCFS_ENTRY_CHECK(dp);
+       LPROCFS_ENTRY_AND_CHECK(dp);
        rc = seq_open(file, &lod_osts_sops);
-       if (rc)
+       if (rc) {
+               LPROCFS_EXIT();
                return rc;
+       }
 
        seq = file->private_data;
        seq->private = dp->data;
index 850bb39..1c5839c 100644 (file)
@@ -252,10 +252,12 @@ static int lov_target_seq_open(struct inode *inode, struct file *file)
         struct seq_file *seq;
         int rc;
 
-       LPROCFS_ENTRY_CHECK(dp);
+        LPROCFS_ENTRY_AND_CHECK(dp);
         rc = seq_open(file, &lov_tgt_sops);
-       if (rc)
+        if (rc) {
+                LPROCFS_EXIT();
                 return rc;
+        }
 
         seq = file->private_data;
         seq->private = dp->data;
index ea2187a..37a4da1 100644 (file)
@@ -541,12 +541,14 @@ static int lprocfs_open_agent_actions(struct inode *inode, struct file *file)
        struct mdt_device               *mdt;
        ENTRY;
 
-       if (LPROCFS_ENTRY_CHECK(PDE(inode)))
+       if (LPROCFS_ENTRY_AND_CHECK(PDE(inode)))
                RETURN(-ENOENT);
 
        rc = seq_open(file, &mdt_agent_actions_proc_ops);
-       if (rc)
+       if (rc) {
+               LPROCFS_EXIT();
                RETURN(rc);
+       }
 
        OBD_ALLOC_PTR(aai);
        if (aai == NULL)
index f67e426..dab281b 100644 (file)
@@ -420,12 +420,14 @@ static int lprocfs_jobstats_seq_open(struct inode *inode, struct file *file)
        struct seq_file *seq;
        int rc;
 
-       if (LPROCFS_ENTRY_CHECK(dp))
+       if (LPROCFS_ENTRY_AND_CHECK(dp))
                return -ENOENT;
 
        rc = seq_open(file, &lprocfs_jobstats_seq_sops);
-       if (rc)
+       if (rc) {
+               LPROCFS_EXIT();
                return rc;
+       }
        seq = file->private_data;
        seq->private = dp->data;
        return 0;
index 6544034..8b52d52 100644 (file)
@@ -62,12 +62,14 @@ EXPORT_SYMBOL(_lprocfs_lock);
 
 int lprocfs_single_release(struct inode *inode, struct file *file)
 {
+        LPROCFS_EXIT();
         return single_release(inode, file);
 }
 EXPORT_SYMBOL(lprocfs_single_release);
 
 int lprocfs_seq_release(struct inode *inode, struct file *file)
 {
+        LPROCFS_EXIT();
         return seq_release(inode, file);
 }
 EXPORT_SYMBOL(lprocfs_seq_release);
@@ -203,7 +205,7 @@ static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
         if (page == NULL)
                 return -ENOMEM;
 
-       if (LPROCFS_ENTRY_CHECK(dp)) {
+        if (LPROCFS_ENTRY_AND_CHECK(dp)) {
                 rc = -ENOENT;
                 goto out;
         }
@@ -212,6 +214,7 @@ static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
         if (dp->read_proc)
                rc = dp->read_proc(page, &start, *ppos, PAGE_CACHE_SIZE,
                                    &eof, dp->data);
+        LPROCFS_EXIT();
         if (rc <= 0)
                 goto out;
 
@@ -247,10 +250,11 @@ static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
         struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
         int rc = -EIO;
 
-       if (LPROCFS_ENTRY_CHECK(dp))
+        if (LPROCFS_ENTRY_AND_CHECK(dp))
                 return -ENOENT;
         if (dp->write_proc)
                 rc = dp->write_proc(f, buf, size, dp->data);
+        LPROCFS_EXIT();
         return rc;
 }
 
@@ -1468,12 +1472,14 @@ static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
         struct seq_file *seq;
         int rc;
 
-       if (LPROCFS_ENTRY_CHECK(dp))
+        if (LPROCFS_ENTRY_AND_CHECK(dp))
                 return -ENOENT;
 
         rc = seq_open(file, &lprocfs_stats_seq_sops);
-       if (rc)
+        if (rc) {
+                LPROCFS_EXIT();
                 return rc;
+        }
         seq = file->private_data;
         seq->private = dp->data;
         return 0;
index e2ba1ee..47ed364 100644 (file)
@@ -992,10 +992,12 @@ ptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file)
         struct seq_file       *seqf;
         int                    rc;
 
-       LPROCFS_ENTRY_CHECK(dp);
+        LPROCFS_ENTRY_AND_CHECK(dp);
         rc = seq_open(file, &sops);
-       if (rc)
+        if (rc) {
+                LPROCFS_EXIT();
                 return rc;
+        }
 
         seqf = file->private_data;
         seqf->private = dp->data;
@@ -1240,6 +1242,14 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
                 goto out;
         }
         tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
+        /* Kludge code(deadlock situation): the lprocfs lock has been held
+         * since the client is evicted by writting client's
+         * uuid/nid to procfs "evict_client" entry. However,
+         * obd_export_evict_by_uuid() will call lprocfs_remove() to destroy
+         * the proc entries under the being destroyed export{}, so I have
+         * to drop the lock at first here.
+         * - jay, jxiong@clusterfs.com */
+        LPROCFS_EXIT();
        class_incref(obd, __FUNCTION__, cfs_current());
 
         if (strncmp(tmpbuf, "nid:", 4) == 0)
@@ -1250,6 +1260,7 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
                 obd_export_evict_by_uuid(obd, tmpbuf);
 
        class_decref(obd, __FUNCTION__, cfs_current());
+        LPROCFS_ENTRY();
 
 out:
         OBD_FREE(kbuf, BUFLEN);
index 791f47d..38f3bb2 100644 (file)
@@ -280,19 +280,21 @@ static int lprocfs_quota_seq_open(struct inode *inode, struct file *file)
                goto out_lqp;
        }
 
-       if (LPROCFS_ENTRY_CHECK(dp)) {
+       if (LPROCFS_ENTRY_AND_CHECK(dp)) {
                rc = -ENOENT;
                goto out_env;
        }
 
        rc = seq_open(file, &lprocfs_quota_seq_sops);
        if (rc)
-               goto out_env;
+               goto out_lprocfs;
 
        seq = file->private_data;
        seq->private = lqp;
        return 0;
 
+out_lprocfs:
+       LPROCFS_EXIT();
 out_env:
        lu_env_fini(&lqp->lqp_env);
 out_lqp:
@@ -305,6 +307,8 @@ static int lprocfs_quota_seq_release(struct inode *inode, struct file *file)
        struct seq_file         *seq = file->private_data;
        struct lquota_procfs    *lqp = seq->private;
 
+       LPROCFS_EXIT();
+
        LASSERT(lqp);
        lu_env_fini(&lqp->lqp_env);
        OBD_FREE_PTR(lqp);