aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c184
1 files changed, 94 insertions, 90 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e5210519ac4b..8e86aaceb68a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -2,7 +2,7 @@
2 * fs/cifs/dir.c 2 * fs/cifs/dir.c
3 * 3 *
4 * vfs operations that deal with dentries 4 * vfs operations that deal with dentries
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2002,2005 6 * Copyright (C) International Business Machines Corp., 2002,2005
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
@@ -34,11 +34,12 @@
34static void 34static void
35renew_parental_timestamps(struct dentry *direntry) 35renew_parental_timestamps(struct dentry *direntry)
36{ 36{
37 /* BB check if there is a way to get the kernel to do this or if we really need this */ 37 /* BB check if there is a way to get the kernel to do this or if we
38 really need this */
38 do { 39 do {
39 direntry->d_time = jiffies; 40 direntry->d_time = jiffies;
40 direntry = direntry->d_parent; 41 direntry = direntry->d_parent;
41 } while (!IS_ROOT(direntry)); 42 } while (!IS_ROOT(direntry));
42} 43}
43 44
44/* Note: caller must free return buffer */ 45/* Note: caller must free return buffer */
@@ -51,7 +52,7 @@ build_path_from_dentry(struct dentry *direntry)
51 char *full_path; 52 char *full_path;
52 char dirsep; 53 char dirsep;
53 54
54 if(direntry == NULL) 55 if (direntry == NULL)
55 return NULL; /* not much we can do if dentry is freed and 56 return NULL; /* not much we can do if dentry is freed and
56 we need to reopen the file after it was closed implicitly 57 we need to reopen the file after it was closed implicitly
57 when the server crashed */ 58 when the server crashed */
@@ -59,18 +60,18 @@ build_path_from_dentry(struct dentry *direntry)
59 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 60 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
60 pplen = CIFS_SB(direntry->d_sb)->prepathlen; 61 pplen = CIFS_SB(direntry->d_sb)->prepathlen;
61cifs_bp_rename_retry: 62cifs_bp_rename_retry:
62 namelen = pplen; 63 namelen = pplen;
63 for (temp = direntry; !IS_ROOT(temp);) { 64 for (temp = direntry; !IS_ROOT(temp);) {
64 namelen += (1 + temp->d_name.len); 65 namelen += (1 + temp->d_name.len);
65 temp = temp->d_parent; 66 temp = temp->d_parent;
66 if(temp == NULL) { 67 if (temp == NULL) {
67 cERROR(1,("corrupt dentry")); 68 cERROR(1, ("corrupt dentry"));
68 return NULL; 69 return NULL;
69 } 70 }
70 } 71 }
71 72
72 full_path = kmalloc(namelen+1, GFP_KERNEL); 73 full_path = kmalloc(namelen+1, GFP_KERNEL);
73 if(full_path == NULL) 74 if (full_path == NULL)
74 return full_path; 75 return full_path;
75 full_path[namelen] = 0; /* trailing null */ 76 full_path[namelen] = 0; /* trailing null */
76 for (temp = direntry; !IS_ROOT(temp);) { 77 for (temp = direntry; !IS_ROOT(temp);) {
@@ -84,8 +85,8 @@ cifs_bp_rename_retry:
84 cFYI(0, ("name: %s", full_path + namelen)); 85 cFYI(0, ("name: %s", full_path + namelen));
85 } 86 }
86 temp = temp->d_parent; 87 temp = temp->d_parent;
87 if(temp == NULL) { 88 if (temp == NULL) {
88 cERROR(1,("corrupt dentry")); 89 cERROR(1, ("corrupt dentry"));
89 kfree(full_path); 90 kfree(full_path);
90 return NULL; 91 return NULL;
91 } 92 }
@@ -94,7 +95,7 @@ cifs_bp_rename_retry:
94 cERROR(1, 95 cERROR(1,
95 ("did not end path lookup where expected namelen is %d", 96 ("did not end path lookup where expected namelen is %d",
96 namelen)); 97 namelen));
97 /* presumably this is only possible if racing with a rename 98 /* presumably this is only possible if racing with a rename
98 of one of the parent directories (we can not lock the dentries 99 of one of the parent directories (we can not lock the dentries
99 above us to prevent this, but retrying should be harmless) */ 100 above us to prevent this, but retrying should be harmless) */
100 kfree(full_path); 101 kfree(full_path);
@@ -106,7 +107,7 @@ cifs_bp_rename_retry:
106 since the '\' is a valid posix character so we can not switch 107 since the '\' is a valid posix character so we can not switch
107 those safely to '/' if any are found in the middle of the prepath */ 108 those safely to '/' if any are found in the middle of the prepath */
108 /* BB test paths to Windows with '/' in the midst of prepath */ 109 /* BB test paths to Windows with '/' in the midst of prepath */
109 strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen); 110 strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen);
110 return full_path; 111 return full_path;
111} 112}
112 113
@@ -147,12 +148,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
147 pTcon = cifs_sb->tcon; 148 pTcon = cifs_sb->tcon;
148 149
149 full_path = build_path_from_dentry(direntry); 150 full_path = build_path_from_dentry(direntry);
150 if(full_path == NULL) { 151 if (full_path == NULL) {
151 FreeXid(xid); 152 FreeXid(xid);
152 return -ENOMEM; 153 return -ENOMEM;
153 } 154 }
154 155
155 if(nd && (nd->flags & LOOKUP_OPEN)) { 156 if (nd && (nd->flags & LOOKUP_OPEN)) {
156 int oflags = nd->intent.open.flags; 157 int oflags = nd->intent.open.flags;
157 158
158 desiredAccess = 0; 159 desiredAccess = 0;
@@ -164,28 +165,29 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
164 write_only = TRUE; 165 write_only = TRUE;
165 } 166 }
166 167
167 if((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 168 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
168 disposition = FILE_CREATE; 169 disposition = FILE_CREATE;
169 else if((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) 170 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
170 disposition = FILE_OVERWRITE_IF; 171 disposition = FILE_OVERWRITE_IF;
171 else if((oflags & O_CREAT) == O_CREAT) 172 else if ((oflags & O_CREAT) == O_CREAT)
172 disposition = FILE_OPEN_IF; 173 disposition = FILE_OPEN_IF;
173 else { 174 else {
174 cFYI(1,("Create flag not set in create function")); 175 cFYI(1, ("Create flag not set in create function"));
175 } 176 }
176 } 177 }
177 178
178 /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ 179 /* BB add processing to set equivalent of mode - e.g. via CreateX with
180 ACLs */
179 if (oplockEnabled) 181 if (oplockEnabled)
180 oplock = REQ_OPLOCK; 182 oplock = REQ_OPLOCK;
181 183
182 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); 184 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
183 if(buf == NULL) { 185 if (buf == NULL) {
184 kfree(full_path); 186 kfree(full_path);
185 FreeXid(xid); 187 FreeXid(xid);
186 return -ENOMEM; 188 return -ENOMEM;
187 } 189 }
188 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 190 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
189 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 191 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
190 desiredAccess, CREATE_NOT_DIR, 192 desiredAccess, CREATE_NOT_DIR,
191 &fileHandle, &oplock, buf, cifs_sb->local_nls, 193 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -193,27 +195,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
193 else 195 else
194 rc = -EIO; /* no NT SMB support fall into legacy open below */ 196 rc = -EIO; /* no NT SMB support fall into legacy open below */
195 197
196 if(rc == -EIO) { 198 if (rc == -EIO) {
197 /* old server, retry the open legacy style */ 199 /* old server, retry the open legacy style */
198 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, 200 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
199 desiredAccess, CREATE_NOT_DIR, 201 desiredAccess, CREATE_NOT_DIR,
200 &fileHandle, &oplock, buf, cifs_sb->local_nls, 202 &fileHandle, &oplock, buf, cifs_sb->local_nls,
201 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 203 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
202 } 204 }
203 if (rc) { 205 if (rc) {
204 cFYI(1, ("cifs_create returned 0x%x", rc)); 206 cFYI(1, ("cifs_create returned 0x%x", rc));
205 } else { 207 } else {
206 /* If Open reported that we actually created a file 208 /* If Open reported that we actually created a file
207 then we now have to set the mode if possible */ 209 then we now have to set the mode if possible */
208 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 210 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
209 (oplock & CIFS_CREATE_ACTION)) 211 (oplock & CIFS_CREATE_ACTION)) {
210 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 212 mode &= ~current->fs->umask;
213 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
211 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 214 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
212 (__u64)current->fsuid, 215 (__u64)current->fsuid,
213 (__u64)current->fsgid, 216 (__u64)current->fsgid,
214 0 /* dev */, 217 0 /* dev */,
215 cifs_sb->local_nls, 218 cifs_sb->local_nls,
216 cifs_sb->mnt_cifs_flags & 219 cifs_sb->mnt_cifs_flags &
217 CIFS_MOUNT_MAP_SPECIAL_CHR); 220 CIFS_MOUNT_MAP_SPECIAL_CHR);
218 } else { 221 } else {
219 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 222 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -221,26 +224,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
221 (__u64)-1, 224 (__u64)-1,
222 0 /* dev */, 225 0 /* dev */,
223 cifs_sb->local_nls, 226 cifs_sb->local_nls,
224 cifs_sb->mnt_cifs_flags & 227 cifs_sb->mnt_cifs_flags &
225 CIFS_MOUNT_MAP_SPECIAL_CHR); 228 CIFS_MOUNT_MAP_SPECIAL_CHR);
226 } 229 }
227 else { 230 } else {
228 /* BB implement mode setting via Windows security descriptors */ 231 /* BB implement mode setting via Windows security
229 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ 232 descriptors e.g. */
230 /* could set r/o dos attribute if mode & 0222 == 0 */ 233 /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
234
235 /* Could set r/o dos attribute if mode & 0222 == 0 */
231 } 236 }
232 237
233 /* BB server might mask mode so we have to query for Unix case*/ 238 /* BB server might mask mode so we have to query for Unix case*/
234 if (pTcon->ses->capabilities & CAP_UNIX) 239 if (pTcon->ses->capabilities & CAP_UNIX)
235 rc = cifs_get_inode_info_unix(&newinode, full_path, 240 rc = cifs_get_inode_info_unix(&newinode, full_path,
236 inode->i_sb,xid); 241 inode->i_sb, xid);
237 else { 242 else {
238 rc = cifs_get_inode_info(&newinode, full_path, 243 rc = cifs_get_inode_info(&newinode, full_path,
239 buf, inode->i_sb,xid); 244 buf, inode->i_sb, xid);
240 if(newinode) { 245 if (newinode) {
241 newinode->i_mode = mode; 246 newinode->i_mode = mode;
242 if((oplock & CIFS_CREATE_ACTION) && 247 if ((oplock & CIFS_CREATE_ACTION) &&
243 (cifs_sb->mnt_cifs_flags & 248 (cifs_sb->mnt_cifs_flags &
244 CIFS_MOUNT_SET_UID)) { 249 CIFS_MOUNT_SET_UID)) {
245 newinode->i_uid = current->fsuid; 250 newinode->i_uid = current->fsuid;
246 newinode->i_gid = current->fsgid; 251 newinode->i_gid = current->fsgid;
@@ -259,14 +264,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
259 direntry->d_op = &cifs_dentry_ops; 264 direntry->d_op = &cifs_dentry_ops;
260 d_instantiate(direntry, newinode); 265 d_instantiate(direntry, newinode);
261 } 266 }
262 if((nd->flags & LOOKUP_OPEN) == FALSE) { 267 if ((nd->flags & LOOKUP_OPEN) == FALSE) {
263 /* mknod case - do not leave file open */ 268 /* mknod case - do not leave file open */
264 CIFSSMBClose(xid, pTcon, fileHandle); 269 CIFSSMBClose(xid, pTcon, fileHandle);
265 } else if(newinode) { 270 } else if (newinode) {
266 pCifsFile = 271 pCifsFile =
267 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 272 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
268 273
269 if(pCifsFile == NULL) 274 if (pCifsFile == NULL)
270 goto cifs_create_out; 275 goto cifs_create_out;
271 pCifsFile->netfid = fileHandle; 276 pCifsFile->netfid = fileHandle;
272 pCifsFile->pid = current->tgid; 277 pCifsFile->pid = current->tgid;
@@ -276,33 +281,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
276 init_MUTEX(&pCifsFile->fh_sem); 281 init_MUTEX(&pCifsFile->fh_sem);
277 mutex_init(&pCifsFile->lock_mutex); 282 mutex_init(&pCifsFile->lock_mutex);
278 INIT_LIST_HEAD(&pCifsFile->llist); 283 INIT_LIST_HEAD(&pCifsFile->llist);
279 atomic_set(&pCifsFile->wrtPending,0); 284 atomic_set(&pCifsFile->wrtPending, 0);
280 285
281 /* set the following in open now 286 /* set the following in open now
282 pCifsFile->pfile = file; */ 287 pCifsFile->pfile = file; */
283 write_lock(&GlobalSMBSeslock); 288 write_lock(&GlobalSMBSeslock);
284 list_add(&pCifsFile->tlist,&pTcon->openFileList); 289 list_add(&pCifsFile->tlist, &pTcon->openFileList);
285 pCifsInode = CIFS_I(newinode); 290 pCifsInode = CIFS_I(newinode);
286 if(pCifsInode) { 291 if (pCifsInode) {
287 /* if readable file instance put first in list*/ 292 /* if readable file instance put first in list*/
288 if (write_only == TRUE) { 293 if (write_only == TRUE) {
289 list_add_tail(&pCifsFile->flist, 294 list_add_tail(&pCifsFile->flist,
290 &pCifsInode->openFileList); 295 &pCifsInode->openFileList);
291 } else { 296 } else {
292 list_add(&pCifsFile->flist, 297 list_add(&pCifsFile->flist,
293 &pCifsInode->openFileList); 298 &pCifsInode->openFileList);
294 } 299 }
295 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 300 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
296 pCifsInode->clientCanCacheAll = TRUE; 301 pCifsInode->clientCanCacheAll = TRUE;
297 pCifsInode->clientCanCacheRead = TRUE; 302 pCifsInode->clientCanCacheRead = TRUE;
298 cFYI(1,("Exclusive Oplock for inode %p", 303 cFYI(1, ("Exclusive Oplock inode %p",
299 newinode)); 304 newinode));
300 } else if((oplock & 0xF) == OPLOCK_READ) 305 } else if ((oplock & 0xF) == OPLOCK_READ)
301 pCifsInode->clientCanCacheRead = TRUE; 306 pCifsInode->clientCanCacheRead = TRUE;
302 } 307 }
303 write_unlock(&GlobalSMBSeslock); 308 write_unlock(&GlobalSMBSeslock);
304 } 309 }
305 } 310 }
306cifs_create_out: 311cifs_create_out:
307 kfree(buf); 312 kfree(buf);
308 kfree(full_path); 313 kfree(full_path);
@@ -310,8 +315,8 @@ cifs_create_out:
310 return rc; 315 return rc;
311} 316}
312 317
313int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, 318int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
314 dev_t device_number) 319 dev_t device_number)
315{ 320{
316 int rc = -EPERM; 321 int rc = -EPERM;
317 int xid; 322 int xid;
@@ -329,43 +334,45 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
329 pTcon = cifs_sb->tcon; 334 pTcon = cifs_sb->tcon;
330 335
331 full_path = build_path_from_dentry(direntry); 336 full_path = build_path_from_dentry(direntry);
332 if(full_path == NULL) 337 if (full_path == NULL)
333 rc = -ENOMEM; 338 rc = -ENOMEM;
334 else if (pTcon->ses->capabilities & CAP_UNIX) { 339 else if (pTcon->ses->capabilities & CAP_UNIX) {
335 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 340 mode &= ~current->fs->umask;
341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
336 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
337 mode,(__u64)current->fsuid,(__u64)current->fsgid, 343 mode, (__u64)current->fsuid,
344 (__u64)current->fsgid,
338 device_number, cifs_sb->local_nls, 345 device_number, cifs_sb->local_nls,
339 cifs_sb->mnt_cifs_flags & 346 cifs_sb->mnt_cifs_flags &
340 CIFS_MOUNT_MAP_SPECIAL_CHR); 347 CIFS_MOUNT_MAP_SPECIAL_CHR);
341 } else { 348 } else {
342 rc = CIFSSMBUnixSetPerms(xid, pTcon, 349 rc = CIFSSMBUnixSetPerms(xid, pTcon,
343 full_path, mode, (__u64)-1, (__u64)-1, 350 full_path, mode, (__u64)-1, (__u64)-1,
344 device_number, cifs_sb->local_nls, 351 device_number, cifs_sb->local_nls,
345 cifs_sb->mnt_cifs_flags & 352 cifs_sb->mnt_cifs_flags &
346 CIFS_MOUNT_MAP_SPECIAL_CHR); 353 CIFS_MOUNT_MAP_SPECIAL_CHR);
347 } 354 }
348 355
349 if(!rc) { 356 if (!rc) {
350 rc = cifs_get_inode_info_unix(&newinode, full_path, 357 rc = cifs_get_inode_info_unix(&newinode, full_path,
351 inode->i_sb,xid); 358 inode->i_sb, xid);
352 if (pTcon->nocase) 359 if (pTcon->nocase)
353 direntry->d_op = &cifs_ci_dentry_ops; 360 direntry->d_op = &cifs_ci_dentry_ops;
354 else 361 else
355 direntry->d_op = &cifs_dentry_ops; 362 direntry->d_op = &cifs_dentry_ops;
356 if(rc == 0) 363 if (rc == 0)
357 d_instantiate(direntry, newinode); 364 d_instantiate(direntry, newinode);
358 } 365 }
359 } else { 366 } else {
360 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 367 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
361 int oplock = 0; 368 int oplock = 0;
362 u16 fileHandle; 369 u16 fileHandle;
363 FILE_ALL_INFO * buf; 370 FILE_ALL_INFO * buf;
364 371
365 cFYI(1,("sfu compat create special file")); 372 cFYI(1, ("sfu compat create special file"));
366 373
367 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); 374 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
368 if(buf == NULL) { 375 if (buf == NULL) {
369 kfree(full_path); 376 kfree(full_path);
370 FreeXid(xid); 377 FreeXid(xid);
371 return -ENOMEM; 378 return -ENOMEM;
@@ -373,39 +380,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
373 380
374 rc = CIFSSMBOpen(xid, pTcon, full_path, 381 rc = CIFSSMBOpen(xid, pTcon, full_path,
375 FILE_CREATE, /* fail if exists */ 382 FILE_CREATE, /* fail if exists */
376 GENERIC_WRITE /* BB would 383 GENERIC_WRITE /* BB would
377 WRITE_OWNER | WRITE_DAC be better? */, 384 WRITE_OWNER | WRITE_DAC be better? */,
378 /* Create a file and set the 385 /* Create a file and set the
379 file attribute to SYSTEM */ 386 file attribute to SYSTEM */
380 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, 387 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
381 &fileHandle, &oplock, buf, 388 &fileHandle, &oplock, buf,
382 cifs_sb->local_nls, 389 cifs_sb->local_nls,
383 cifs_sb->mnt_cifs_flags & 390 cifs_sb->mnt_cifs_flags &
384 CIFS_MOUNT_MAP_SPECIAL_CHR); 391 CIFS_MOUNT_MAP_SPECIAL_CHR);
385 392
386 /* BB FIXME - add handling for backlevel servers 393 /* BB FIXME - add handling for backlevel servers
387 which need legacy open and check for all 394 which need legacy open and check for all
388 calls to SMBOpen for fallback to 395 calls to SMBOpen for fallback to SMBLeagcyOpen */
389 SMBLeagcyOpen */ 396 if (!rc) {
390 if(!rc) {
391 /* BB Do not bother to decode buf since no 397 /* BB Do not bother to decode buf since no
392 local inode yet to put timestamps in, 398 local inode yet to put timestamps in,
393 but we can reuse it safely */ 399 but we can reuse it safely */
394 int bytes_written; 400 int bytes_written;
395 struct win_dev *pdev; 401 struct win_dev *pdev;
396 pdev = (struct win_dev *)buf; 402 pdev = (struct win_dev *)buf;
397 if(S_ISCHR(mode)) { 403 if (S_ISCHR(mode)) {
398 memcpy(pdev->type, "IntxCHR", 8); 404 memcpy(pdev->type, "IntxCHR", 8);
399 pdev->major = 405 pdev->major =
400 cpu_to_le64(MAJOR(device_number)); 406 cpu_to_le64(MAJOR(device_number));
401 pdev->minor = 407 pdev->minor =
402 cpu_to_le64(MINOR(device_number)); 408 cpu_to_le64(MINOR(device_number));
403 rc = CIFSSMBWrite(xid, pTcon, 409 rc = CIFSSMBWrite(xid, pTcon,
404 fileHandle, 410 fileHandle,
405 sizeof(struct win_dev), 411 sizeof(struct win_dev),
406 0, &bytes_written, (char *)pdev, 412 0, &bytes_written, (char *)pdev,
407 NULL, 0); 413 NULL, 0);
408 } else if(S_ISBLK(mode)) { 414 } else if (S_ISBLK(mode)) {
409 memcpy(pdev->type, "IntxBLK", 8); 415 memcpy(pdev->type, "IntxBLK", 8);
410 pdev->major = 416 pdev->major =
411 cpu_to_le64(MAJOR(device_number)); 417 cpu_to_le64(MAJOR(device_number));
@@ -432,7 +438,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
432 438
433 439
434struct dentry * 440struct dentry *
435cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd) 441cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
442 struct nameidata *nd)
436{ 443{
437 int xid; 444 int xid;
438 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 445 int rc = 0; /* to get around spurious gcc warning, set to zero here */
@@ -447,8 +454,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
447 (" parent inode = 0x%p name is: %s and dentry = 0x%p", 454 (" parent inode = 0x%p name is: %s and dentry = 0x%p",
448 parent_dir_inode, direntry->d_name.name, direntry)); 455 parent_dir_inode, direntry->d_name.name, direntry));
449 456
450 /* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */
451
452 /* check whether path exists */ 457 /* check whether path exists */
453 458
454 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 459 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
@@ -472,7 +477,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
472 deadlock in the cases (beginning of sys_rename itself) 477 deadlock in the cases (beginning of sys_rename itself)
473 in which we already have the sb rename sem */ 478 in which we already have the sb rename sem */
474 full_path = build_path_from_dentry(direntry); 479 full_path = build_path_from_dentry(direntry);
475 if(full_path == NULL) { 480 if (full_path == NULL) {
476 FreeXid(xid); 481 FreeXid(xid);
477 return ERR_PTR(-ENOMEM); 482 return ERR_PTR(-ENOMEM);
478 } 483 }
@@ -487,10 +492,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
487 492
488 if (pTcon->ses->capabilities & CAP_UNIX) 493 if (pTcon->ses->capabilities & CAP_UNIX)
489 rc = cifs_get_inode_info_unix(&newInode, full_path, 494 rc = cifs_get_inode_info_unix(&newInode, full_path,
490 parent_dir_inode->i_sb,xid); 495 parent_dir_inode->i_sb, xid);
491 else 496 else
492 rc = cifs_get_inode_info(&newInode, full_path, NULL, 497 rc = cifs_get_inode_info(&newInode, full_path, NULL,
493 parent_dir_inode->i_sb,xid); 498 parent_dir_inode->i_sb, xid);
494 499
495 if ((rc == 0) && (newInode != NULL)) { 500 if ((rc == 0) && (newInode != NULL)) {
496 if (pTcon->nocase) 501 if (pTcon->nocase)
@@ -499,7 +504,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
499 direntry->d_op = &cifs_dentry_ops; 504 direntry->d_op = &cifs_dentry_ops;
500 d_add(direntry, newInode); 505 d_add(direntry, newInode);
501 506
502 /* since paths are not looked up by component - the parent 507 /* since paths are not looked up by component - the parent
503 directories are presumed to be good here */ 508 directories are presumed to be good here */
504 renew_parental_timestamps(direntry); 509 renew_parental_timestamps(direntry);
505 510
@@ -511,13 +516,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
511 else 516 else
512 direntry->d_op = &cifs_dentry_ops; 517 direntry->d_op = &cifs_dentry_ops;
513 d_add(direntry, NULL); 518 d_add(direntry, NULL);
514 /* if it was once a directory (but how can we tell?) we could do 519 /* if it was once a directory (but how can we tell?) we could do
515 shrink_dcache_parent(direntry); */ 520 shrink_dcache_parent(direntry); */
516 } else { 521 } else {
517 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 522 cERROR(1, ("Error 0x%x on cifs_get_inode_info in lookup of %s",
518 rc,full_path)); 523 rc, full_path));
519 /* BB special case check for Access Denied - watch security 524 /* BB special case check for Access Denied - watch security
520 exposure of returning dir info implicitly via different rc 525 exposure of returning dir info implicitly via different rc
521 if file exists or not but no access BB */ 526 if file exists or not but no access BB */
522 } 527 }
523 528
@@ -538,11 +543,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
538 } else { 543 } else {
539 cFYI(1, ("neg dentry 0x%p name = %s", 544 cFYI(1, ("neg dentry 0x%p name = %s",
540 direntry, direntry->d_name.name)); 545 direntry, direntry->d_name.name));
541 if(time_after(jiffies, direntry->d_time + HZ) || 546 if (time_after(jiffies, direntry->d_time + HZ) ||
542 !lookupCacheEnabled) { 547 !lookupCacheEnabled) {
543 d_drop(direntry); 548 d_drop(direntry);
544 isValid = 0; 549 isValid = 0;
545 } 550 }
546 } 551 }
547 552
548 return isValid; 553 return isValid;
@@ -559,8 +564,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
559 564
560struct dentry_operations cifs_dentry_ops = { 565struct dentry_operations cifs_dentry_ops = {
561 .d_revalidate = cifs_d_revalidate, 566 .d_revalidate = cifs_d_revalidate,
562/* d_delete: cifs_d_delete, *//* not needed except for debugging */ 567/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
563 /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
564}; 568};
565 569
566static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) 570static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)