इस पोस्ट को देखने के लिए धन्यवाद। मैं नेटवर्क ब्लॉक डिवाइस ड्राइवर को पैच करने की कोशिश कर रहा हूं। यदि आपको स्रोत देखने की आवश्यकता है तो वे 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
};
तो, मैं निम्नलिखित सलाह पूछना होगा।
क्या यह सही कार्यवाही जैसा दिखता है?
क्या मैं को io फ़ंक्शन में लॉक करने के लिए सही समझता हूं?
crtrldev.c में शामिल के आधार पर, क्या आप के शीर्ष पर किसी भी लॉक को अनुशंसा कर सकते हैं? (मैं कुछ अन्य filp और lock_kernel के साथ काम कर चालकों के लिए अनुसंधान करने की कोशिश की, लेकिन मैं बहुत ज्यादा एक noob हूँ जवाब खोजने के लिए सही दूर।)
इस ड्राइवर में lock_kernel का केवल एक उदाहरण है। मुझे लगता है कि इसका मतलब कोई रिकर्सन नहीं है और संभावना है कि इसे io.c में बदलना पर्याप्त होगा। Mutex के साथ lock_kernel को बदलने के लिए, क्या इसका मतलब है कि मैं थोड़ा फ़ंक्शन लिखूंगा, फिर इसे lock_kernel की बजाय कॉल करें? या क्या मैं डिवाइस में मौजूदा म्यूटेक्स से लिंक करने का प्रयास करता हूं? Ctrldev.c में mutex लॉक के कई संदर्भ हैं। डिवाइस पर एक स्पिन लॉक भी है लेकिन इसे नहीं कहा जाता है। अगर मैं ndas_ctrldev_ioctl फ़ंक्शन के अंदर प्रत्येक संभावित ऑपरेशन के लिए अप() और डाउन() का उपयोग करता हूं तो प्रति डिवाइस शैली पर विचार किया जाएगा? – ndasusers