]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.suse/novfs-clear-mappeddrives.patch
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / novfs-clear-mappeddrives.patch
1 From: Goldwyn Rodrigues <rgoldwyn@suse.de>
2 Subject: Unlink mapped drives on exit
3 References: bnc#449451
4
5 Mapped drives were not being unlinked properly because
6 of ABI change in the kernel. Fixed local_unlink function
7 to correctly unlink files.
8
9 ---
10 fs/novfs/daemon.c | 97 +++++++++++++++++++++++++++++++-----------------------
11 fs/novfs/nwcapi.c | 2 -
12 2 files changed, 57 insertions(+), 42 deletions(-)
13
14 Index: linux-2.6.27/fs/novfs/daemon.c
15 ===================================================================
16 --- linux-2.6.27.orig/fs/novfs/daemon.c 2008-11-27 16:02:22.000000000 +0530
17 +++ linux-2.6.27/fs/novfs/daemon.c 2008-11-28 11:20:08.000000000 +0530
18 @@ -15,6 +15,7 @@
19
20 #include <linux/module.h>
21 #include <linux/fs.h>
22 +#include <linux/mount.h>
23 #include <linux/slab.h>
24 #include <linux/list.h>
25 #include <linux/timer.h>
26 @@ -96,7 +97,7 @@ static int NwdConvertNetwareHandle(struc
27 static int set_map_drive(struct novfs_xplat *pdata, struct novfs_schandle Session);
28 static int unmap_drive(struct novfs_xplat *pdata, struct novfs_schandle Session);
29 static int NwdGetMountPath(struct novfs_xplat *pdata);
30 -static int local_unlink(const char *pathname);
31 +static long local_unlink(const char *pathname);
32
33
34 /*===[ Global variables ]=================================================*/
35 @@ -1610,7 +1611,7 @@ int novfs_daemon_lib_ioctl(struct inode
36
37 case NWC_SET_CONN_INFO:
38 DbgPrint
39 - ("[VFS XPLAT] Call NwGetConnInfo\n");
40 + ("[VFS XPLAT] Call NwSetConnInfo\n");
41 retCode =
42 novfs_set_conn_info(&data, dh->session);
43 break;
44 @@ -2061,54 +2062,68 @@ static void RemoveDriveMaps(void)
45 up(&DriveMapLock);
46 }
47
48 -static int local_unlink(const char *pathname)
49 +/* As picked from do_unlinkat() */
50 +
51 +static long local_unlink(const char *pathname)
52 {
53 int error;
54 struct dentry *dentry;
55 + char *name, *c;
56 struct nameidata nd;
57 struct inode *inode = NULL;
58
59 - DbgPrint("local_unlink: %s\n", pathname);
60 error = path_lookup(pathname, LOOKUP_PARENT, &nd);
61 - DbgPrint("local_unlink: path_lookup %d\n", error);
62 - if (!error) {
63 - error = -EISDIR;
64 - if (nd.last_type == LAST_NORM) {
65 - dentry = lookup_create(&nd, 1);
66 - DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
67 -
68 - error = PTR_ERR(dentry);
69 - if (!IS_ERR(dentry)) {
70 - if (nd.last.name[nd.last.len]) {
71 - error =
72 - !dentry->
73 - d_inode ? -ENOENT : S_ISDIR(dentry->
74 - d_inode->
75 - i_mode)
76 - ? -EISDIR : -ENOTDIR;
77 - } else {
78 - inode = dentry->d_inode;
79 - if (inode) {
80 - atomic_inc(&inode->i_count);
81 - }
82 - error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt);
83 - DbgPrint
84 - ("local_unlink: vfs_unlink %d\n",
85 - error);
86 - }
87 - dput(dentry);
88 - }
89 - mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
90 -
91 - }
92 - path_put(&nd.path);
93 + DbgPrint("local_unlink: path_lookup %s error: %d\n", pathname, error);
94 + if (error)
95 + return error;
96 +
97 + error = -EISDIR;
98 + if (nd.last_type != LAST_NORM)
99 + goto exit1;
100 + mutex_lock(&nd.path.dentry->d_inode->i_mutex);
101 + /* Get the filename of pathname */
102 + name=c=(char *)pathname;
103 + while (*c!='\0') {
104 + if (*c=='/')
105 + name=++c;
106 + c++;
107 + }
108 + dentry = lookup_one_len(name, nd.path.dentry, strlen(name));
109 + error = PTR_ERR(dentry);
110 + DbgPrint("local_unlink: dentry %p\n", dentry);
111 + if (!(dentry->d_inode->i_mode & S_IFLNK)) {
112 + DbgPrint("local_unlink: %s not a link", name);
113 + error=-ENOENT;
114 + goto exit1;
115 + }
116 +
117 + if (!IS_ERR(dentry)) {
118 + /* Why not before? Because we want correct error value */
119 + if (nd.last.name[nd.last.len])
120 + goto slashes;
121 + inode = dentry->d_inode;
122 + if (inode)
123 + atomic_inc(&inode->i_count);
124 + error = mnt_want_write(nd.path.mnt);
125 + DbgPrint("local_unlink: inode %p mnt_want_write error %d\n", inode, error);
126 + if (error)
127 + goto exit2;
128 + error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt);
129 + mnt_drop_write(nd.path.mnt);
130 + exit2:
131 + dput(dentry);
132 }
133 -
134 - if (inode) {
135 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
136 + if (inode)
137 iput(inode); /* truncate the inode here */
138 - }
139 -
140 - DbgPrint("local_unlink: error=%d\n", error);
141 +exit1:
142 + path_put(&nd.path);
143 + DbgPrint("local_unlink: returning error %d\n", error);
144 return error;
145 +
146 +slashes:
147 + error = !dentry->d_inode ? -ENOENT :
148 + S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
149 + goto exit2;
150 }
151
152 Index: linux-2.6.27/fs/novfs/nwcapi.c
153 ===================================================================
154 --- linux-2.6.27.orig/fs/novfs/nwcapi.c 2008-11-27 16:02:22.000000000 +0530
155 +++ linux-2.6.27/fs/novfs/nwcapi.c 2008-11-28 11:02:15.000000000 +0530
156 @@ -993,7 +993,7 @@ int novfs_scan_conn_info(struct novfs_xp
157 DbgPrint("NwScanConnInfo: Reply recieved\n");
158 DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex);
159 DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode);
160 - DbgPrint(" data = %x\n", reply->data);
161 + DbgPrint(" data = %p\n", reply->data);
162
163 pDConnInfo = (struct nwd_scan_conn_info *) reply->data;
164 retCode = (unsigned long) reply->Reply.ErrorCode;