File cdfs-3.7.diff of Package cdfs
From: Jan Engelhardt <jengelh@inai.de>
Date: 2013-03-18 06:38:53.843861391 +0100
build: resolve compile warnings and runtime problems with Linux 3.7
(Applies on top of cdfs-3.3.diff.)
Make cdfs_get_XA_info not use a huge stack frame (resolves a gcc
warning).
Update lookup function type according to changes from Linux kernel commit
00cd8dd3bf95f2cc8435b4cac01d9995635c6d0b. (Resolves gcc warning
about huge stack frame.)
Update thread function according to changes from Linux kernel commit
e76623d69408d0bd66a296c6ee5eae1b17a6adfc.
Resolve an always-occurring ENOMEM when mounting a filesystem.
(Condition inversion)
---
cdXA.c | 17 ++++++++++++-----
cdfs.h | 4 ++--
daemon.c | 45 +++++----------------------------------------
root.c | 15 +++++++++++----
4 files changed, 30 insertions(+), 51 deletions(-)
Index: cdfs-2.6.27/cdXA.c
===================================================================
--- cdfs-2.6.27.orig/cdXA.c
+++ cdfs-2.6.27/cdXA.c
@@ -54,16 +54,21 @@ int cdfs_read_raw_frame(struct super_blo
/***********************************************************/
-void cdfs_get_XA_info(struct super_block * sb, int inode) {
- char frame[CD_FRAMESIZE_RAW0];
+int cdfs_get_XA_info(struct super_block * sb, int inode) {
+ char *frame;
cd * this_cd = cdfs_info(sb);
track_info * this_track = &(this_cd->track[inode]);
unsigned start_lba = this_track->start_lba;
int status;
+ frame = kmalloc(CD_FRAMESIZE_RAW, GFP_KERNEL);
+ if (frame == NULL)
+ return -ENOMEM;
+
if((status = cdfs_read_raw_frame(sb, start_lba, frame))) {
printk("get_XA_info: ioctl failed: %d\n", status);
- return;
+ kfree(frame);
+ return -EIO;
}
if (frame[0] == frame[4] &&
@@ -83,14 +88,16 @@ void cdfs_get_XA_info(struct super_block
// Get type & title
if((status = cdfs_read_raw_frame(sb, 150, frame))) {
printk("get_XA_info: ioctl failed: %d\n", status);
- return;
+ kfree(frame);
+ return -EIO;
}
strncpy(this_cd->videocd_type, frame+this_track->xa_data_offset, 8);
this_cd->videocd_type[8]=0;
strncpy(this_cd->videocd_title, frame+this_track->xa_data_offset+10, 16);
this_cd->videocd_title[16]=0;
-
+ kfree(frame);
+ return 0;
}
/***********************************************************/
Index: cdfs-2.6.27/cdfs.h
===================================================================
--- cdfs-2.6.27.orig/cdfs.h
+++ cdfs-2.6.27/cdfs.h
@@ -176,7 +176,7 @@ int cdfs_ioctl(struct super_block *s, in
struct iso_primary_descriptor * cdfs_get_iso_info(struct super_block *sb, int track_no);
int cdfs_get_hfs_info(struct super_block *sb, unsigned track);
void cdfs_check_bootable(struct super_block *sb);
-void cdfs_get_XA_info(struct super_block * sb, int inode);
+int cdfs_get_XA_info(struct super_block * sb, int inode);
void cdfs_copy_from_cdXA(struct super_block * sb, int inode, unsigned int start,
unsigned int stop, char * buf);
void cdfs_copy_from_cddata(struct super_block * sb, int inode, unsigned int start,
@@ -194,7 +194,7 @@ int kcdfsd_add_cdhfs_request(struct file
int kcdfsd_add_request(struct dentry *dentry, struct page *page, unsigned type);
int kcdfsd_thread(void *unused);
void kcdfsd_cleanup_thread(void);
-extern int kcdfsd_pid;
+extern struct task_struct *kcdfsd_thr;
/* for discid stuff */
unsigned long discid(cd *);
Index: cdfs-2.6.27/daemon.c
===================================================================
--- cdfs-2.6.27.orig/daemon.c
+++ cdfs-2.6.27/daemon.c
@@ -28,9 +28,10 @@
#include "cdfs.h"
+#include <linux/kthread.h>
#include <linux/sched.h>
-int kcdfsd_pid = 0;
+struct task_struct *kcdfsd_thr;
static int kcdfsd_running = 0;
static DECLARE_WAIT_QUEUE_HEAD(kcdfsd_wait);
static LIST_HEAD(kcdfsd_req_list); /* List of requests needing servicing */
@@ -150,29 +151,10 @@ static void kcdfsd_process_request(void)
int kcdfsd_thread(void *unused){
kcdfsd_running = 1;
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources
- */
-#ifdef OLD_KERNEL
- exit_files(current); /* daemonize doesn't do exit_files */
- daemonize();
-#else
- daemonize("k"FSNAME"d");
-
- /* Allow SIGTERM to quit properly when removing module */
- /* By default with daemonize all signals are dropped */
- allow_signal(SIGTERM);
-#endif
-
- /* Setup a nice name */
- strcpy(current->comm, "k"FSNAME"d");
-
- /* Send me a signal to get me die */
- do {
+ while (!kthread_should_stop()) {
kcdfsd_process_request();
interruptible_sleep_on(&kcdfsd_wait);
- } while (!signal_pending(current));
+ }
kcdfsd_running = 0;
return 0;
@@ -181,22 +163,5 @@ int kcdfsd_thread(void *unused){
/****************************************************************************/
void kcdfsd_cleanup_thread(){
- int ret;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
- ret = kill_proc(kcdfsd_pid, SIGTERM, 1);
-#else
- ret = kill_pid(find_vpid(kcdfsd_pid), SIGTERM, 1);
-#endif
-
- if (!ret) {
- /* Wait 10 seconds */
- int count = 10 * HZ;
-
- while (kcdfsd_running && --count) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
- if (!count)
- printk(FSNAME": Giving up on killing k"FSNAME"d!\n");
- }
+ kthread_stop(kcdfsd_thr);
}
Index: cdfs-2.6.27/root.c
===================================================================
--- cdfs-2.6.27.orig/root.c
+++ cdfs-2.6.27/root.c
@@ -24,6 +24,7 @@
#include "cdfs.h"
+#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/sched.h>
@@ -247,8 +248,11 @@ static int cdfs_fill_super(struct super_
cdfs_get_hfs_info(sb, i); // possibly also a HFS
} else { // DATA, but no ISO -> either HFS or VideoCD
if (cdfs_get_hfs_info(sb, i)==-1){
+ int ret;
printk("CHECKING VIDEOCD!!\n");
- cdfs_get_XA_info(sb, i);
+ ret = cdfs_get_XA_info(sb, i);
+ if (ret < 0)
+ return ret;
this_cd->track[i].time = 0;
this_cd->track[i].iso_size = 0;
this_cd->track[i].track_size = (this_cd->track[i].track_size-1) * this_cd->track[i].xa_data_size;
@@ -377,8 +381,10 @@ out:
PRINT("retinode = %ld\n", retinode->i_ino);
sb->s_root = d_make_root(retinode);
- if (sb->s_root != NULL)
+ if (sb->s_root == NULL) {
+ iput(retinode);
return -ENOMEM;
+ }
cdfs_proc_cd = this_cd;
@@ -466,7 +472,7 @@ static int cdfs_readdir(struct file *fil
#ifdef OLD_KERNEL
static struct dentry * cdfs_lookup(struct inode *dir, struct dentry *dentry){
#else
-static struct dentry * cdfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+static struct dentry * cdfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int x){
#endif
struct inode * inode;
int i;
@@ -640,7 +646,8 @@ static int __init cdfs_init(void) {
cdfs_proc_cd=NULL;
// start kernel thread
- if ((kcdfsd_pid = kernel_thread(kcdfsd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) >0 ) {
+ kcdfsd_thr = kthread_run(kcdfsd_thread, NULL, "kcdfsd");
+ if (kcdfsd_thr != NULL) {
return 0;
} else {
printk(FSNAME" kernel_thread failed.\n");