2011-05-10 10 views
5

इस पोस्ट को देखने के लिए धन्यवाद। मैं नेटवर्क ब्लॉक डिवाइस ड्राइवर को पैच करने की कोशिश कर रहा हूं। यदि आपको स्रोत देखने की आवश्यकता है तो वे http: ///code.ximeta.com पर हैं।क्या कोई मुझे ब्लॉक डिवाइस ड्राइवर पर "lock_kernel" को बदलने में मदद कर सकता है?

मैंने देखा कि lock_kernel() linux 2.6.37 के रूप में बहिष्कृत लगता है। मैंने "ioctl()" का नया तरीका पढ़ा और पाया कि डिवाइस ड्राइवरों को अब ऑपरेटिंग से पहले एक विशिष्ट लॉक करना चाहिए।

तो यदि संभव हो तो मुझे कुछ सलाह देना चाहूंगा।

मुझे ब्लॉक फ़ोल्डर खंड में, मौजूदा कोड में दो खंड मिले हैं जो मुझे लगता है।

Source 
     block->io.c 
      ->ctrldev.c 

मैंने आपके विचार के लिए प्रत्येक से स्निपेट डाले।

io.c एक lock_kernel करने के लिए कॉल शामिल हैं:

NDAS_SAL_API xbool  sal_file_get_size(sal_file file, xuint64* size) 
{ 
    definitions and declarations etc.. 

lock_kernel(); 

#ifdef HAVE_UNLOCKED_IOCTL 
    if (filp->f_op->unlocked_ioctl) { 
     some small statements 

     error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size); 

     actions if error or not etc. 
    } 
#endif 

    unlock_kernel(); 
    return ret; 
} 

और ctrldev.c मुख्य कब समारोह में शामिल है:

#include <linux/spinlock.h> // spinklock_t 
#include <linux/semaphore.h> // struct semaphore 
#include <asm/atomic.h> // atomic 
#include <linux/interrupt.h> 
#include <linux/fs.h> 
#include <asm/uaccess.h> 
#include <linux/ide.h> 
#include <linux/smp_lock.h> 
#include <linux/time.h> 

...... 

int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 
{ 
    lots of operations and functions. 

    return result; 
} 

बाद ndas_ctrldev_ioctl समारोह पूर्व .ioctl के रूप में स्थापित किया जाएगा।

static struct file_operations ndasctrl_fops = { 
    .write = ndas_ctrldev_write, 
    .read = ndas_ctrldev_read, 
    .open = ndas_ctrldev_open, 
    .release = ndas_ctrldev_release, 
    .ioctl = ndas_ctrldev_ioctl, 
}; 

अब मैं इसे lock_kernel() का उपयोग करने से बचने के लिए परिवर्तित करना चाहता हूं;

मेरी समझ के अनुसार मैं नीचे के रूप में पूर्व वर्गों संशोधित होगा:

NDAS_SAL_API xbool  sal_file_get_size(sal_file file, xuint64* size) 
{ 
    definitions and declarations etc.. 

#ifndef HAVE_UNLOCKED_IOCTL 
    lock_kernel(); 
#endif 

#ifdef HAVE_UNLOCKED_IOCTL 
    if (filp->f_op->unlocked_ioctl) { 
     some small statements 

     error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size); 

     actions if error or not etc. 
    } 
#endif 

#ifndef HAVE_UNLOCKED_IOCTL 
    unlock_kernel(); 
#endif 
    return ret; 

} 

#ifdef HAVE_UNLOCKED_IOCTL 
long ndas_ctrldev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 
#else 
int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 
#endif 
{ 

#ifdef HAVE_UNLOCKED_IOCTL 
    ! add some sort of lock here ! 
#endif 

    lots of operations and functions. 

#ifdef HAVE_UNLOCKED_IOCTL 
    ! add unlock statement here ! 
#endif 
    return result; 
} 

static struct file_operations ndasctrl_fops = { 
    .write = ndas_ctrldev_write, 
    .read = ndas_ctrldev_read, 
    .open = ndas_ctrldev_open, 
    .release = ndas_ctrldev_release, 
#ifdef HAVE_UNLOCKED_IOCTL 
    .unlocked_ioctl = ndas_ctrldev_ioctl, 
#else 
    .ioctl = ndas_ctrldev_ioctl, 
#endif 
}; 

तो, मैं निम्नलिखित सलाह पूछना होगा।

  1. क्या यह सही कार्यवाही जैसा दिखता है?

  2. क्या मैं को io फ़ंक्शन में लॉक करने के लिए सही समझता हूं?

  3. crtrldev.c में शामिल के आधार पर, क्या आप के शीर्ष पर किसी भी लॉक को अनुशंसा कर सकते हैं? (मैं कुछ अन्य filp और lock_kernel के साथ काम कर चालकों के लिए अनुसंधान करने की कोशिश की, लेकिन मैं बहुत ज्यादा एक noob हूँ जवाब खोजने के लिए सही दूर।)

उत्तर

5

की तुलना में अधिक पदावनत बिग कर्नेल लॉक (BKL) है 2.6.3 9 के रूप में, यह अब अस्तित्व में नहीं है।

जिस तरह से lock_kernel() रूपांतरण किया गया था प्रति ड्राइवर म्यूटेक्स द्वारा इसे प्रतिस्थापित करना था। यदि ड्राइवर पर्याप्त सरल है, तो आप बस ड्राइवर के लिए एक म्यूटेक्स बना सकते हैं, और म्यूटेक्स लॉक/अनलॉक कॉल द्वारा lock_kernel() और unlock_kernel() के सभी उपयोगों को प्रतिस्थापित कर सकते हैं। नोट, हालांकि, कुछ कार्यों को बीकेएल (लॉक lock_kernel() लॉक करने के लिए उपयोग किया जाता है) के साथ बुलाया जाता था; आपको इन कार्यों में भी लॉक/अनलॉक कॉल जोड़ना होगा।

यह काम नहीं करेगा अगर चालक बीकेएल को दोबारा हासिल कर सके; यदि ऐसा है, तो आपको डेडलॉक्स से बचने के लिए इसे स्वयं ट्रैक करना होगा (यह reiserfs के रूपांतरण में किया गया था, जो रिकर्सिव बीकेएल व्यवहार में कुछ हद तक निर्भर था और इस तथ्य में कि सोने के दौरान इसे गिरा दिया गया था)।

प्रति-चालक म्यूटेक्स में रूपांतरण के बाद अगला चरण प्रति-चालक म्यूटेक्स के बजाय प्रति डिवाइस म्यूटेक्स का उपयोग करने के लिए इसे बदलना होगा।

+0

इस ड्राइवर में lock_kernel का केवल एक उदाहरण है। मुझे लगता है कि इसका मतलब कोई रिकर्सन नहीं है और संभावना है कि इसे io.c में बदलना पर्याप्त होगा। Mutex के साथ lock_kernel को बदलने के लिए, क्या इसका मतलब है कि मैं थोड़ा फ़ंक्शन लिखूंगा, फिर इसे lock_kernel की बजाय कॉल करें? या क्या मैं डिवाइस में मौजूदा म्यूटेक्स से लिंक करने का प्रयास करता हूं? Ctrldev.c में mutex लॉक के कई संदर्भ हैं। डिवाइस पर एक स्पिन लॉक भी है लेकिन इसे नहीं कहा जाता है। अगर मैं ndas_ctrldev_ioctl फ़ंक्शन के अंदर प्रत्येक संभावित ऑपरेशन के लिए अप() और डाउन() का उपयोग करता हूं तो प्रति डिवाइस शैली पर विचार किया जाएगा? – ndasusers

5

यहां समाधान है।

#if HAVE_UNLOCKED_IOCTL 
    #include <linux/mutex.h> 
#else 
    #include <linux/smp_lock.h> 
#endif 

. 
. 
. 

#if HAVE_UNLOCKED_IOCTL 
    mutex_lock(&fs_mutex); 
#else 
    lock_kernel(); 
#endif 

यह केवल लॉक कॉल को प्रतिस्थापित करता है। अन्य हिस्सों ने काम किया क्योंकि मैंने अनलॉक_ऑक्टेल से संबंधित प्रश्न भाग में अनुमान लगाया था। जांच और मदद के लिए धन्यवाद।

संबंधित मुद्दे