diff options
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3f3538d4a1fa..c619d45060ce 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -43,7 +43,7 @@ renew_parental_timestamps(struct dentry *direntry) | |||
43 | 43 | ||
44 | /* Note: caller must free return buffer */ | 44 | /* Note: caller must free return buffer */ |
45 | char * | 45 | char * |
46 | build_path_from_dentry(struct dentry *direntry) | 46 | build_path_from_dentry(struct dentry *direntry, const struct cifs_sb_info *cifs_sb) |
47 | { | 47 | { |
48 | struct dentry *temp; | 48 | struct dentry *temp; |
49 | int namelen = 0; | 49 | int namelen = 0; |
@@ -74,7 +74,7 @@ cifs_bp_rename_retry: | |||
74 | if (namelen < 0) { | 74 | if (namelen < 0) { |
75 | break; | 75 | break; |
76 | } else { | 76 | } else { |
77 | full_path[namelen] = '\\'; | 77 | full_path[namelen] = CIFS_DIR_SEP(cifs_sb); |
78 | strncpy(full_path + namelen + 1, temp->d_name.name, | 78 | strncpy(full_path + namelen + 1, temp->d_name.name, |
79 | temp->d_name.len); | 79 | temp->d_name.len); |
80 | cFYI(0, (" name: %s ", full_path + namelen)); | 80 | cFYI(0, (" name: %s ", full_path + namelen)); |
@@ -138,7 +138,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
138 | pTcon = cifs_sb->tcon; | 138 | pTcon = cifs_sb->tcon; |
139 | 139 | ||
140 | down(&direntry->d_sb->s_vfs_rename_sem); | 140 | down(&direntry->d_sb->s_vfs_rename_sem); |
141 | full_path = build_path_from_dentry(direntry); | 141 | full_path = build_path_from_dentry(direntry, cifs_sb); |
142 | up(&direntry->d_sb->s_vfs_rename_sem); | 142 | up(&direntry->d_sb->s_vfs_rename_sem); |
143 | if(full_path == NULL) { | 143 | if(full_path == NULL) { |
144 | FreeXid(xid); | 144 | FreeXid(xid); |
@@ -209,7 +209,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
209 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 209 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
210 | } | 210 | } |
211 | else { | 211 | else { |
212 | /* BB implement via Windows security descriptors */ | 212 | /* BB implement mode setting via Windows security descriptors */ |
213 | /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ | 213 | /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ |
214 | /* could set r/o dos attribute if mode & 0222 == 0 */ | 214 | /* could set r/o dos attribute if mode & 0222 == 0 */ |
215 | } | 215 | } |
@@ -226,7 +226,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
226 | } | 226 | } |
227 | 227 | ||
228 | if (rc != 0) { | 228 | if (rc != 0) { |
229 | cFYI(1,("Create worked but get_inode_info failed with rc = %d", | 229 | cFYI(1, |
230 | ("Create worked but get_inode_info failed rc = %d", | ||
230 | rc)); | 231 | rc)); |
231 | } else { | 232 | } else { |
232 | direntry->d_op = &cifs_dentry_ops; | 233 | direntry->d_op = &cifs_dentry_ops; |
@@ -299,12 +300,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
299 | pTcon = cifs_sb->tcon; | 300 | pTcon = cifs_sb->tcon; |
300 | 301 | ||
301 | down(&direntry->d_sb->s_vfs_rename_sem); | 302 | down(&direntry->d_sb->s_vfs_rename_sem); |
302 | full_path = build_path_from_dentry(direntry); | 303 | full_path = build_path_from_dentry(direntry, cifs_sb); |
303 | up(&direntry->d_sb->s_vfs_rename_sem); | 304 | up(&direntry->d_sb->s_vfs_rename_sem); |
304 | if(full_path == NULL) | 305 | if(full_path == NULL) |
305 | rc = -ENOMEM; | 306 | rc = -ENOMEM; |
306 | 307 | else if (pTcon->ses->capabilities & CAP_UNIX) { | |
307 | if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) { | ||
308 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 308 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
309 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 309 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
310 | mode,(__u64)current->euid,(__u64)current->egid, | 310 | mode,(__u64)current->euid,(__u64)current->egid, |
@@ -326,6 +326,42 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
326 | if(rc == 0) | 326 | if(rc == 0) |
327 | d_instantiate(direntry, newinode); | 327 | d_instantiate(direntry, newinode); |
328 | } | 328 | } |
329 | } else { | ||
330 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | ||
331 | int oplock = 0; | ||
332 | u16 fileHandle; | ||
333 | FILE_ALL_INFO * buf; | ||
334 | |||
335 | cFYI(1,("sfu compat create special file")); | ||
336 | |||
337 | buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); | ||
338 | if(buf == NULL) { | ||
339 | kfree(full_path); | ||
340 | FreeXid(xid); | ||
341 | return -ENOMEM; | ||
342 | } | ||
343 | |||
344 | rc = CIFSSMBOpen(xid, pTcon, full_path, | ||
345 | FILE_CREATE, /* fail if exists */ | ||
346 | GENERIC_WRITE /* BB would | ||
347 | WRITE_OWNER | WRITE_DAC be better? */, | ||
348 | /* Create a file and set the | ||
349 | file attribute to SYSTEM */ | ||
350 | CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | ||
351 | &fileHandle, &oplock, buf, | ||
352 | cifs_sb->local_nls, | ||
353 | cifs_sb->mnt_cifs_flags & | ||
354 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
355 | |||
356 | if(!rc) { | ||
357 | /* BB Do not bother to decode buf since no | ||
358 | local inode yet to put timestamps in */ | ||
359 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
360 | d_drop(direntry); | ||
361 | } | ||
362 | kfree(buf); | ||
363 | /* add code here to set EAs */ | ||
364 | } | ||
329 | } | 365 | } |
330 | 366 | ||
331 | kfree(full_path); | 367 | kfree(full_path); |
@@ -360,7 +396,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
360 | /* can not grab the rename sem here since it would | 396 | /* can not grab the rename sem here since it would |
361 | deadlock in the cases (beginning of sys_rename itself) | 397 | deadlock in the cases (beginning of sys_rename itself) |
362 | in which we already have the sb rename sem */ | 398 | in which we already have the sb rename sem */ |
363 | full_path = build_path_from_dentry(direntry); | 399 | full_path = build_path_from_dentry(direntry, cifs_sb); |
364 | if(full_path == NULL) { | 400 | if(full_path == NULL) { |
365 | FreeXid(xid); | 401 | FreeXid(xid); |
366 | return ERR_PTR(-ENOMEM); | 402 | return ERR_PTR(-ENOMEM); |