aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/dir.c172
-rw-r--r--fs/cifs/fcntl.c46
-rw-r--r--fs/cifs/ioctl.c29
-rw-r--r--fs/cifs/rfc1002pdu.h2
4 files changed, 124 insertions, 125 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e5210519ac4b..eeab602c6e0a 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,13 +195,13 @@ 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 {
@@ -207,13 +209,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
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 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
211 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 213 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
212 (__u64)current->fsuid, 214 (__u64)current->fsuid,
213 (__u64)current->fsgid, 215 (__u64)current->fsgid,
214 0 /* dev */, 216 0 /* dev */,
215 cifs_sb->local_nls, 217 cifs_sb->local_nls,
216 cifs_sb->mnt_cifs_flags & 218 cifs_sb->mnt_cifs_flags &
217 CIFS_MOUNT_MAP_SPECIAL_CHR); 219 CIFS_MOUNT_MAP_SPECIAL_CHR);
218 } else { 220 } else {
219 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 221 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -221,26 +223,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
221 (__u64)-1, 223 (__u64)-1,
222 0 /* dev */, 224 0 /* dev */,
223 cifs_sb->local_nls, 225 cifs_sb->local_nls,
224 cifs_sb->mnt_cifs_flags & 226 cifs_sb->mnt_cifs_flags &
225 CIFS_MOUNT_MAP_SPECIAL_CHR); 227 CIFS_MOUNT_MAP_SPECIAL_CHR);
226 } 228 }
227 else { 229 else {
228 /* BB implement mode setting via Windows security descriptors */ 230 /* BB implement mode setting via Windows security
229 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ 231 descriptors e.g. */
230 /* could set r/o dos attribute if mode & 0222 == 0 */ 232 /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
233
234 /* Could set r/o dos attribute if mode & 0222 == 0 */
231 } 235 }
232 236
233 /* BB server might mask mode so we have to query for Unix case*/ 237 /* BB server might mask mode so we have to query for Unix case*/
234 if (pTcon->ses->capabilities & CAP_UNIX) 238 if (pTcon->ses->capabilities & CAP_UNIX)
235 rc = cifs_get_inode_info_unix(&newinode, full_path, 239 rc = cifs_get_inode_info_unix(&newinode, full_path,
236 inode->i_sb,xid); 240 inode->i_sb, xid);
237 else { 241 else {
238 rc = cifs_get_inode_info(&newinode, full_path, 242 rc = cifs_get_inode_info(&newinode, full_path,
239 buf, inode->i_sb,xid); 243 buf, inode->i_sb, xid);
240 if(newinode) { 244 if (newinode) {
241 newinode->i_mode = mode; 245 newinode->i_mode = mode;
242 if((oplock & CIFS_CREATE_ACTION) && 246 if ((oplock & CIFS_CREATE_ACTION) &&
243 (cifs_sb->mnt_cifs_flags & 247 (cifs_sb->mnt_cifs_flags &
244 CIFS_MOUNT_SET_UID)) { 248 CIFS_MOUNT_SET_UID)) {
245 newinode->i_uid = current->fsuid; 249 newinode->i_uid = current->fsuid;
246 newinode->i_gid = current->fsgid; 250 newinode->i_gid = current->fsgid;
@@ -259,14 +263,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
259 direntry->d_op = &cifs_dentry_ops; 263 direntry->d_op = &cifs_dentry_ops;
260 d_instantiate(direntry, newinode); 264 d_instantiate(direntry, newinode);
261 } 265 }
262 if((nd->flags & LOOKUP_OPEN) == FALSE) { 266 if ((nd->flags & LOOKUP_OPEN) == FALSE) {
263 /* mknod case - do not leave file open */ 267 /* mknod case - do not leave file open */
264 CIFSSMBClose(xid, pTcon, fileHandle); 268 CIFSSMBClose(xid, pTcon, fileHandle);
265 } else if(newinode) { 269 } else if (newinode) {
266 pCifsFile = 270 pCifsFile =
267 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 271 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
268 272
269 if(pCifsFile == NULL) 273 if (pCifsFile == NULL)
270 goto cifs_create_out; 274 goto cifs_create_out;
271 pCifsFile->netfid = fileHandle; 275 pCifsFile->netfid = fileHandle;
272 pCifsFile->pid = current->tgid; 276 pCifsFile->pid = current->tgid;
@@ -276,33 +280,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
276 init_MUTEX(&pCifsFile->fh_sem); 280 init_MUTEX(&pCifsFile->fh_sem);
277 mutex_init(&pCifsFile->lock_mutex); 281 mutex_init(&pCifsFile->lock_mutex);
278 INIT_LIST_HEAD(&pCifsFile->llist); 282 INIT_LIST_HEAD(&pCifsFile->llist);
279 atomic_set(&pCifsFile->wrtPending,0); 283 atomic_set(&pCifsFile->wrtPending, 0);
280 284
281 /* set the following in open now 285 /* set the following in open now
282 pCifsFile->pfile = file; */ 286 pCifsFile->pfile = file; */
283 write_lock(&GlobalSMBSeslock); 287 write_lock(&GlobalSMBSeslock);
284 list_add(&pCifsFile->tlist,&pTcon->openFileList); 288 list_add(&pCifsFile->tlist, &pTcon->openFileList);
285 pCifsInode = CIFS_I(newinode); 289 pCifsInode = CIFS_I(newinode);
286 if(pCifsInode) { 290 if (pCifsInode) {
287 /* if readable file instance put first in list*/ 291 /* if readable file instance put first in list*/
288 if (write_only == TRUE) { 292 if (write_only == TRUE) {
289 list_add_tail(&pCifsFile->flist, 293 list_add_tail(&pCifsFile->flist,
290 &pCifsInode->openFileList); 294 &pCifsInode->openFileList);
291 } else { 295 } else {
292 list_add(&pCifsFile->flist, 296 list_add(&pCifsFile->flist,
293 &pCifsInode->openFileList); 297 &pCifsInode->openFileList);
294 } 298 }
295 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 299 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
296 pCifsInode->clientCanCacheAll = TRUE; 300 pCifsInode->clientCanCacheAll = TRUE;
297 pCifsInode->clientCanCacheRead = TRUE; 301 pCifsInode->clientCanCacheRead = TRUE;
298 cFYI(1,("Exclusive Oplock for inode %p", 302 cFYI(1,("Exclusive Oplock for inode %p",
299 newinode)); 303 newinode));
300 } else if((oplock & 0xF) == OPLOCK_READ) 304 } else if ((oplock & 0xF) == OPLOCK_READ)
301 pCifsInode->clientCanCacheRead = TRUE; 305 pCifsInode->clientCanCacheRead = TRUE;
302 } 306 }
303 write_unlock(&GlobalSMBSeslock); 307 write_unlock(&GlobalSMBSeslock);
304 } 308 }
305 } 309 }
306cifs_create_out: 310cifs_create_out:
307 kfree(buf); 311 kfree(buf);
308 kfree(full_path); 312 kfree(full_path);
@@ -310,8 +314,8 @@ cifs_create_out:
310 return rc; 314 return rc;
311} 315}
312 316
313int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, 317int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
314 dev_t device_number) 318 dev_t device_number)
315{ 319{
316 int rc = -EPERM; 320 int rc = -EPERM;
317 int xid; 321 int xid;
@@ -329,43 +333,44 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
329 pTcon = cifs_sb->tcon; 333 pTcon = cifs_sb->tcon;
330 334
331 full_path = build_path_from_dentry(direntry); 335 full_path = build_path_from_dentry(direntry);
332 if(full_path == NULL) 336 if (full_path == NULL)
333 rc = -ENOMEM; 337 rc = -ENOMEM;
334 else if (pTcon->ses->capabilities & CAP_UNIX) { 338 else if (pTcon->ses->capabilities & CAP_UNIX) {
335 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 339 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
336 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 340 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
337 mode,(__u64)current->fsuid,(__u64)current->fsgid, 341 mode, (__u64)current->fsuid,
342 (__u64)current->fsgid,
338 device_number, cifs_sb->local_nls, 343 device_number, cifs_sb->local_nls,
339 cifs_sb->mnt_cifs_flags & 344 cifs_sb->mnt_cifs_flags &
340 CIFS_MOUNT_MAP_SPECIAL_CHR); 345 CIFS_MOUNT_MAP_SPECIAL_CHR);
341 } else { 346 } else {
342 rc = CIFSSMBUnixSetPerms(xid, pTcon, 347 rc = CIFSSMBUnixSetPerms(xid, pTcon,
343 full_path, mode, (__u64)-1, (__u64)-1, 348 full_path, mode, (__u64)-1, (__u64)-1,
344 device_number, cifs_sb->local_nls, 349 device_number, cifs_sb->local_nls,
345 cifs_sb->mnt_cifs_flags & 350 cifs_sb->mnt_cifs_flags &
346 CIFS_MOUNT_MAP_SPECIAL_CHR); 351 CIFS_MOUNT_MAP_SPECIAL_CHR);
347 } 352 }
348 353
349 if(!rc) { 354 if (!rc) {
350 rc = cifs_get_inode_info_unix(&newinode, full_path, 355 rc = cifs_get_inode_info_unix(&newinode, full_path,
351 inode->i_sb,xid); 356 inode->i_sb, xid);
352 if (pTcon->nocase) 357 if (pTcon->nocase)
353 direntry->d_op = &cifs_ci_dentry_ops; 358 direntry->d_op = &cifs_ci_dentry_ops;
354 else 359 else
355 direntry->d_op = &cifs_dentry_ops; 360 direntry->d_op = &cifs_dentry_ops;
356 if(rc == 0) 361 if (rc == 0)
357 d_instantiate(direntry, newinode); 362 d_instantiate(direntry, newinode);
358 } 363 }
359 } else { 364 } else {
360 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 365 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
361 int oplock = 0; 366 int oplock = 0;
362 u16 fileHandle; 367 u16 fileHandle;
363 FILE_ALL_INFO * buf; 368 FILE_ALL_INFO * buf;
364 369
365 cFYI(1,("sfu compat create special file")); 370 cFYI(1, ("sfu compat create special file"));
366 371
367 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); 372 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
368 if(buf == NULL) { 373 if (buf == NULL) {
369 kfree(full_path); 374 kfree(full_path);
370 FreeXid(xid); 375 FreeXid(xid);
371 return -ENOMEM; 376 return -ENOMEM;
@@ -373,39 +378,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
373 378
374 rc = CIFSSMBOpen(xid, pTcon, full_path, 379 rc = CIFSSMBOpen(xid, pTcon, full_path,
375 FILE_CREATE, /* fail if exists */ 380 FILE_CREATE, /* fail if exists */
376 GENERIC_WRITE /* BB would 381 GENERIC_WRITE /* BB would
377 WRITE_OWNER | WRITE_DAC be better? */, 382 WRITE_OWNER | WRITE_DAC be better? */,
378 /* Create a file and set the 383 /* Create a file and set the
379 file attribute to SYSTEM */ 384 file attribute to SYSTEM */
380 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, 385 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
381 &fileHandle, &oplock, buf, 386 &fileHandle, &oplock, buf,
382 cifs_sb->local_nls, 387 cifs_sb->local_nls,
383 cifs_sb->mnt_cifs_flags & 388 cifs_sb->mnt_cifs_flags &
384 CIFS_MOUNT_MAP_SPECIAL_CHR); 389 CIFS_MOUNT_MAP_SPECIAL_CHR);
385 390
386 /* BB FIXME - add handling for backlevel servers 391 /* BB FIXME - add handling for backlevel servers
387 which need legacy open and check for all 392 which need legacy open and check for all
388 calls to SMBOpen for fallback to 393 calls to SMBOpen for fallback to SMBLeagcyOpen */
389 SMBLeagcyOpen */ 394 if (!rc) {
390 if(!rc) {
391 /* BB Do not bother to decode buf since no 395 /* BB Do not bother to decode buf since no
392 local inode yet to put timestamps in, 396 local inode yet to put timestamps in,
393 but we can reuse it safely */ 397 but we can reuse it safely */
394 int bytes_written; 398 int bytes_written;
395 struct win_dev *pdev; 399 struct win_dev *pdev;
396 pdev = (struct win_dev *)buf; 400 pdev = (struct win_dev *)buf;
397 if(S_ISCHR(mode)) { 401 if (S_ISCHR(mode)) {
398 memcpy(pdev->type, "IntxCHR", 8); 402 memcpy(pdev->type, "IntxCHR", 8);
399 pdev->major = 403 pdev->major =
400 cpu_to_le64(MAJOR(device_number)); 404 cpu_to_le64(MAJOR(device_number));
401 pdev->minor = 405 pdev->minor =
402 cpu_to_le64(MINOR(device_number)); 406 cpu_to_le64(MINOR(device_number));
403 rc = CIFSSMBWrite(xid, pTcon, 407 rc = CIFSSMBWrite(xid, pTcon,
404 fileHandle, 408 fileHandle,
405 sizeof(struct win_dev), 409 sizeof(struct win_dev),
406 0, &bytes_written, (char *)pdev, 410 0, &bytes_written, (char *)pdev,
407 NULL, 0); 411 NULL, 0);
408 } else if(S_ISBLK(mode)) { 412 } else if (S_ISBLK(mode)) {
409 memcpy(pdev->type, "IntxBLK", 8); 413 memcpy(pdev->type, "IntxBLK", 8);
410 pdev->major = 414 pdev->major =
411 cpu_to_le64(MAJOR(device_number)); 415 cpu_to_le64(MAJOR(device_number));
@@ -432,7 +436,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
432 436
433 437
434struct dentry * 438struct dentry *
435cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd) 439cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
440 struct nameidata *nd)
436{ 441{
437 int xid; 442 int xid;
438 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 443 int rc = 0; /* to get around spurious gcc warning, set to zero here */
@@ -447,8 +452,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", 452 (" parent inode = 0x%p name is: %s and dentry = 0x%p",
448 parent_dir_inode, direntry->d_name.name, direntry)); 453 parent_dir_inode, direntry->d_name.name, direntry));
449 454
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 */ 455 /* check whether path exists */
453 456
454 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 457 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
@@ -472,7 +475,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
472 deadlock in the cases (beginning of sys_rename itself) 475 deadlock in the cases (beginning of sys_rename itself)
473 in which we already have the sb rename sem */ 476 in which we already have the sb rename sem */
474 full_path = build_path_from_dentry(direntry); 477 full_path = build_path_from_dentry(direntry);
475 if(full_path == NULL) { 478 if (full_path == NULL) {
476 FreeXid(xid); 479 FreeXid(xid);
477 return ERR_PTR(-ENOMEM); 480 return ERR_PTR(-ENOMEM);
478 } 481 }
@@ -487,10 +490,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
487 490
488 if (pTcon->ses->capabilities & CAP_UNIX) 491 if (pTcon->ses->capabilities & CAP_UNIX)
489 rc = cifs_get_inode_info_unix(&newInode, full_path, 492 rc = cifs_get_inode_info_unix(&newInode, full_path,
490 parent_dir_inode->i_sb,xid); 493 parent_dir_inode->i_sb, xid);
491 else 494 else
492 rc = cifs_get_inode_info(&newInode, full_path, NULL, 495 rc = cifs_get_inode_info(&newInode, full_path, NULL,
493 parent_dir_inode->i_sb,xid); 496 parent_dir_inode->i_sb, xid);
494 497
495 if ((rc == 0) && (newInode != NULL)) { 498 if ((rc == 0) && (newInode != NULL)) {
496 if (pTcon->nocase) 499 if (pTcon->nocase)
@@ -499,7 +502,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
499 direntry->d_op = &cifs_dentry_ops; 502 direntry->d_op = &cifs_dentry_ops;
500 d_add(direntry, newInode); 503 d_add(direntry, newInode);
501 504
502 /* since paths are not looked up by component - the parent 505 /* since paths are not looked up by component - the parent
503 directories are presumed to be good here */ 506 directories are presumed to be good here */
504 renew_parental_timestamps(direntry); 507 renew_parental_timestamps(direntry);
505 508
@@ -511,13 +514,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
511 else 514 else
512 direntry->d_op = &cifs_dentry_ops; 515 direntry->d_op = &cifs_dentry_ops;
513 d_add(direntry, NULL); 516 d_add(direntry, NULL);
514 /* if it was once a directory (but how can we tell?) we could do 517 /* if it was once a directory (but how can we tell?) we could do
515 shrink_dcache_parent(direntry); */ 518 shrink_dcache_parent(direntry); */
516 } else { 519 } else {
517 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 520 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
518 rc,full_path)); 521 rc, full_path));
519 /* BB special case check for Access Denied - watch security 522 /* BB special case check for Access Denied - watch security
520 exposure of returning dir info implicitly via different rc 523 exposure of returning dir info implicitly via different rc
521 if file exists or not but no access BB */ 524 if file exists or not but no access BB */
522 } 525 }
523 526
@@ -538,11 +541,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
538 } else { 541 } else {
539 cFYI(1, ("neg dentry 0x%p name = %s", 542 cFYI(1, ("neg dentry 0x%p name = %s",
540 direntry, direntry->d_name.name)); 543 direntry, direntry->d_name.name));
541 if(time_after(jiffies, direntry->d_time + HZ) || 544 if (time_after(jiffies, direntry->d_time + HZ) ||
542 !lookupCacheEnabled) { 545 !lookupCacheEnabled) {
543 d_drop(direntry); 546 d_drop(direntry);
544 isValid = 0; 547 isValid = 0;
545 } 548 }
546 } 549 }
547 550
548 return isValid; 551 return isValid;
@@ -559,8 +562,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
559 562
560struct dentry_operations cifs_dentry_ops = { 563struct dentry_operations cifs_dentry_ops = {
561 .d_revalidate = cifs_d_revalidate, 564 .d_revalidate = cifs_d_revalidate,
562/* d_delete: cifs_d_delete, *//* not needed except for debugging */ 565/* 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}; 566};
565 567
566static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) 568static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index da12b482ebe5..8e375bb4b379 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -2,7 +2,7 @@
2 * fs/cifs/fcntl.c 2 * fs/cifs/fcntl.c
3 * 3 *
4 * vfs operations that deal with the file control API 4 * vfs operations that deal with the file control API
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2003,2004 6 * Copyright (C) International Business Machines Corp., 2003,2004
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
@@ -35,35 +35,34 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
35 35
36 /* No way on Linux VFS to ask to monitor xattr 36 /* No way on Linux VFS to ask to monitor xattr
37 changes (and no stream support either */ 37 changes (and no stream support either */
38 if(fcntl_notify_flags & DN_ACCESS) { 38 if (fcntl_notify_flags & DN_ACCESS) {
39 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; 39 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
40 } 40 }
41 if(fcntl_notify_flags & DN_MODIFY) { 41 if (fcntl_notify_flags & DN_MODIFY) {
42 /* What does this mean on directories? */ 42 /* What does this mean on directories? */
43 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | 43 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
44 FILE_NOTIFY_CHANGE_SIZE; 44 FILE_NOTIFY_CHANGE_SIZE;
45 } 45 }
46 if(fcntl_notify_flags & DN_CREATE) { 46 if (fcntl_notify_flags & DN_CREATE) {
47 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | 47 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION |
48 FILE_NOTIFY_CHANGE_LAST_WRITE; 48 FILE_NOTIFY_CHANGE_LAST_WRITE;
49 } 49 }
50 if(fcntl_notify_flags & DN_DELETE) { 50 if (fcntl_notify_flags & DN_DELETE) {
51 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; 51 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
52 } 52 }
53 if(fcntl_notify_flags & DN_RENAME) { 53 if (fcntl_notify_flags & DN_RENAME) {
54 /* BB review this - checking various server behaviors */ 54 /* BB review this - checking various server behaviors */
55 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | 55 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME |
56 FILE_NOTIFY_CHANGE_FILE_NAME; 56 FILE_NOTIFY_CHANGE_FILE_NAME;
57 } 57 }
58 if(fcntl_notify_flags & DN_ATTRIB) { 58 if (fcntl_notify_flags & DN_ATTRIB) {
59 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY | 59 cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY |
60 FILE_NOTIFY_CHANGE_ATTRIBUTES; 60 FILE_NOTIFY_CHANGE_ATTRIBUTES;
61 } 61 }
62/* if(fcntl_notify_flags & DN_MULTISHOT) { 62/* if (fcntl_notify_flags & DN_MULTISHOT) {
63 cifs_ntfy_flags |= ; 63 cifs_ntfy_flags |= ;
64 } */ /* BB fixme - not sure how to handle this with CIFS yet */ 64 } */ /* BB fixme - not sure how to handle this with CIFS yet */
65 65
66
67 return cifs_ntfy_flags; 66 return cifs_ntfy_flags;
68} 67}
69 68
@@ -78,8 +77,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
78 __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; 77 __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
79 __u16 netfid; 78 __u16 netfid;
80 79
81 80 if (experimEnabled == 0)
82 if(experimEnabled == 0)
83 return 0; 81 return 0;
84 82
85 xid = GetXid(); 83 xid = GetXid();
@@ -88,21 +86,21 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
88 86
89 full_path = build_path_from_dentry(file->f_path.dentry); 87 full_path = build_path_from_dentry(file->f_path.dentry);
90 88
91 if(full_path == NULL) { 89 if (full_path == NULL) {
92 rc = -ENOMEM; 90 rc = -ENOMEM;
93 } else { 91 } else {
94 cFYI(1,("dir notify on file %s Arg 0x%lx",full_path,arg)); 92 cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg));
95 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 93 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
96 GENERIC_READ | SYNCHRONIZE, 0 /* create options */, 94 GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
97 &netfid, &oplock,NULL, cifs_sb->local_nls, 95 &netfid, &oplock, NULL, cifs_sb->local_nls,
98 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 96 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
99 /* BB fixme - add this handle to a notify handle list */ 97 /* BB fixme - add this handle to a notify handle list */
100 if(rc) { 98 if (rc) {
101 cFYI(1,("Could not open directory for notify")); 99 cFYI(1, ("Could not open directory for notify"));
102 } else { 100 } else {
103 filter = convert_to_cifs_notify_flags(arg); 101 filter = convert_to_cifs_notify_flags(arg);
104 if(filter != 0) { 102 if (filter != 0) {
105 rc = CIFSSMBNotify(xid, pTcon, 103 rc = CIFSSMBNotify(xid, pTcon,
106 0 /* no subdirs */, netfid, 104 0 /* no subdirs */, netfid,
107 filter, file, arg & DN_MULTISHOT, 105 filter, file, arg & DN_MULTISHOT,
108 cifs_sb->local_nls); 106 cifs_sb->local_nls);
@@ -113,10 +111,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
113 it would close automatically but may be a way 111 it would close automatically but may be a way
114 to do it easily when inode freed or when 112 to do it easily when inode freed or when
115 notify info is cleared/changed */ 113 notify info is cleared/changed */
116 cFYI(1,("notify rc %d",rc)); 114 cFYI(1, ("notify rc %d", rc));
117 } 115 }
118 } 116 }
119 117
120 FreeXid(xid); 118 FreeXid(xid);
121 return rc; 119 return rc;
122} 120}
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index e34c7db00f6f..a414f1775ae0 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -30,7 +30,7 @@
30 30
31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) 31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
32 32
33int cifs_ioctl (struct inode * inode, struct file * filep, 33int cifs_ioctl (struct inode * inode, struct file * filep,
34 unsigned int command, unsigned long arg) 34 unsigned int command, unsigned long arg)
35{ 35{
36 int rc = -ENOTTY; /* strange error - but the precedent */ 36 int rc = -ENOTTY; /* strange error - but the precedent */
@@ -47,13 +47,13 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
47 47
48 xid = GetXid(); 48 xid = GetXid();
49 49
50 cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); 50 cFYI(1, ("ioctl file %p cmd %u arg %lu", filep, command, arg));
51 51
52 cifs_sb = CIFS_SB(inode->i_sb); 52 cifs_sb = CIFS_SB(inode->i_sb);
53 53
54#ifdef CONFIG_CIFS_POSIX 54#ifdef CONFIG_CIFS_POSIX
55 tcon = cifs_sb->tcon; 55 tcon = cifs_sb->tcon;
56 if(tcon) 56 if (tcon)
57 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); 57 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
58 else { 58 else {
59 rc = -EIO; 59 rc = -EIO;
@@ -62,24 +62,24 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
62 } 62 }
63#endif /* CONFIG_CIFS_POSIX */ 63#endif /* CONFIG_CIFS_POSIX */
64 64
65 switch(command) { 65 switch (command) {
66 case CIFS_IOC_CHECKUMOUNT: 66 case CIFS_IOC_CHECKUMOUNT:
67 cFYI(1,("User unmount attempted")); 67 cFYI(1, ("User unmount attempted"));
68 if(cifs_sb->mnt_uid == current->uid) 68 if (cifs_sb->mnt_uid == current->uid)
69 rc = 0; 69 rc = 0;
70 else { 70 else {
71 rc = -EACCES; 71 rc = -EACCES;
72 cFYI(1,("uids do not match")); 72 cFYI(1, ("uids do not match"));
73 } 73 }
74 break; 74 break;
75#ifdef CONFIG_CIFS_POSIX 75#ifdef CONFIG_CIFS_POSIX
76 case FS_IOC_GETFLAGS: 76 case FS_IOC_GETFLAGS:
77 if(CIFS_UNIX_EXTATTR_CAP & caps) { 77 if (CIFS_UNIX_EXTATTR_CAP & caps) {
78 if (pSMBFile == NULL) 78 if (pSMBFile == NULL)
79 break; 79 break;
80 rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, 80 rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
81 &ExtAttrBits, &ExtAttrMask); 81 &ExtAttrBits, &ExtAttrMask);
82 if(rc == 0) 82 if (rc == 0)
83 rc = put_user(ExtAttrBits & 83 rc = put_user(ExtAttrBits &
84 FS_FL_USER_VISIBLE, 84 FS_FL_USER_VISIBLE,
85 (int __user *)arg); 85 (int __user *)arg);
@@ -87,8 +87,8 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
87 break; 87 break;
88 88
89 case FS_IOC_SETFLAGS: 89 case FS_IOC_SETFLAGS:
90 if(CIFS_UNIX_EXTATTR_CAP & caps) { 90 if (CIFS_UNIX_EXTATTR_CAP & caps) {
91 if(get_user(ExtAttrBits,(int __user *)arg)) { 91 if (get_user(ExtAttrBits, (int __user *)arg)) {
92 rc = -EFAULT; 92 rc = -EFAULT;
93 break; 93 break;
94 } 94 }
@@ -96,16 +96,15 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
96 break; 96 break;
97 /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, 97 /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
98 extAttrBits, &ExtAttrMask);*/ 98 extAttrBits, &ExtAttrMask);*/
99
100 } 99 }
101 cFYI(1,("set flags not implemented yet")); 100 cFYI(1, ("set flags not implemented yet"));
102 break; 101 break;
103#endif /* CONFIG_CIFS_POSIX */ 102#endif /* CONFIG_CIFS_POSIX */
104 default: 103 default:
105 cFYI(1,("unsupported ioctl")); 104 cFYI(1, ("unsupported ioctl"));
106 break; 105 break;
107 } 106 }
108 107
109 FreeXid(xid); 108 FreeXid(xid);
110 return rc; 109 return rc;
111} 110}
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h
index aede606132aa..8b69fcceb597 100644
--- a/fs/cifs/rfc1002pdu.h
+++ b/fs/cifs/rfc1002pdu.h
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU Lesser General Public License 19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software 20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ 24/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */