diff options
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 108 |
1 files changed, 17 insertions, 91 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 12ba81d7b07f..e3137aa48cdd 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -101,68 +101,15 @@ cifs_bp_rename_retry: | |||
101 | return full_path; | 101 | return full_path; |
102 | } | 102 | } |
103 | 103 | ||
104 | /* Note: caller must free return buffer */ | 104 | /* char * build_wildcard_path_from_dentry(struct dentry *direntry) |
105 | char * | ||
106 | build_wildcard_path_from_dentry(struct dentry *direntry) | ||
107 | { | 105 | { |
108 | struct dentry *temp; | ||
109 | int namelen = 0; | ||
110 | char *full_path; | ||
111 | |||
112 | if(direntry == NULL) | ||
113 | return NULL; /* not much we can do if dentry is freed and | ||
114 | we need to reopen the file after it was closed implicitly | ||
115 | when the server crashed */ | ||
116 | |||
117 | cifs_bwp_rename_retry: | ||
118 | for (temp = direntry; !IS_ROOT(temp);) { | ||
119 | namelen += (1 + temp->d_name.len); | ||
120 | temp = temp->d_parent; | ||
121 | if(temp == NULL) { | ||
122 | cERROR(1,("corrupt dentry")); | ||
123 | return NULL; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | full_path = kmalloc(namelen+3, GFP_KERNEL); | ||
128 | if(full_path == NULL) | 106 | if(full_path == NULL) |
129 | return full_path; | 107 | return full_path; |
130 | 108 | ||
131 | full_path[namelen] = '\\'; | 109 | full_path[namelen] = '\\'; |
132 | full_path[namelen+1] = '*'; | 110 | full_path[namelen+1] = '*'; |
133 | full_path[namelen+2] = 0; /* trailing null */ | 111 | full_path[namelen+2] = 0; |
134 | 112 | BB remove above eight lines BB */ | |
135 | for (temp = direntry; !IS_ROOT(temp);) { | ||
136 | namelen -= 1 + temp->d_name.len; | ||
137 | if (namelen < 0) { | ||
138 | break; | ||
139 | } else { | ||
140 | full_path[namelen] = '\\'; | ||
141 | strncpy(full_path + namelen + 1, temp->d_name.name, | ||
142 | temp->d_name.len); | ||
143 | cFYI(0, (" name: %s ", full_path + namelen)); | ||
144 | } | ||
145 | temp = temp->d_parent; | ||
146 | if(temp == NULL) { | ||
147 | cERROR(1,("corrupt dentry")); | ||
148 | kfree(full_path); | ||
149 | return NULL; | ||
150 | } | ||
151 | } | ||
152 | if (namelen != 0) { | ||
153 | cERROR(1, | ||
154 | ("We did not end path lookup where we expected namelen is %d", | ||
155 | namelen)); | ||
156 | /* presumably this is only possible if we were racing with a rename | ||
157 | of one of the parent directories (we can not lock the dentries | ||
158 | above us to prevent this, but retrying should be harmless) */ | ||
159 | kfree(full_path); | ||
160 | namelen = 0; | ||
161 | goto cifs_bwp_rename_retry; | ||
162 | } | ||
163 | |||
164 | return full_path; | ||
165 | } | ||
166 | 113 | ||
167 | /* Inode operations in similar order to how they appear in the Linux file fs.h */ | 114 | /* Inode operations in similar order to how they appear in the Linux file fs.h */ |
168 | 115 | ||
@@ -235,7 +182,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
235 | 182 | ||
236 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 183 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
237 | desiredAccess, CREATE_NOT_DIR, | 184 | desiredAccess, CREATE_NOT_DIR, |
238 | &fileHandle, &oplock, buf, cifs_sb->local_nls); | 185 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
186 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
239 | if (rc) { | 187 | if (rc) { |
240 | cFYI(1, ("cifs_create returned 0x%x ", rc)); | 188 | cFYI(1, ("cifs_create returned 0x%x ", rc)); |
241 | } else { | 189 | } else { |
@@ -248,13 +196,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
248 | (__u64)current->euid, | 196 | (__u64)current->euid, |
249 | (__u64)current->egid, | 197 | (__u64)current->egid, |
250 | 0 /* dev */, | 198 | 0 /* dev */, |
251 | cifs_sb->local_nls); | 199 | cifs_sb->local_nls, |
200 | cifs_sb->mnt_cifs_flags & | ||
201 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
252 | } else { | 202 | } else { |
253 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 203 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
254 | (__u64)-1, | 204 | (__u64)-1, |
255 | (__u64)-1, | 205 | (__u64)-1, |
256 | 0 /* dev */, | 206 | 0 /* dev */, |
257 | cifs_sb->local_nls); | 207 | cifs_sb->local_nls, |
208 | cifs_sb->mnt_cifs_flags & | ||
209 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
258 | } | 210 | } |
259 | else { | 211 | else { |
260 | /* BB implement via Windows security descriptors */ | 212 | /* BB implement via Windows security descriptors */ |
@@ -356,11 +308,15 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
356 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 308 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
357 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 309 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
358 | mode,(__u64)current->euid,(__u64)current->egid, | 310 | mode,(__u64)current->euid,(__u64)current->egid, |
359 | device_number, cifs_sb->local_nls); | 311 | device_number, cifs_sb->local_nls, |
312 | cifs_sb->mnt_cifs_flags & | ||
313 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
360 | } else { | 314 | } else { |
361 | rc = CIFSSMBUnixSetPerms(xid, pTcon, | 315 | rc = CIFSSMBUnixSetPerms(xid, pTcon, |
362 | full_path, mode, (__u64)-1, (__u64)-1, | 316 | full_path, mode, (__u64)-1, (__u64)-1, |
363 | device_number, cifs_sb->local_nls); | 317 | device_number, cifs_sb->local_nls, |
318 | cifs_sb->mnt_cifs_flags & | ||
319 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
364 | } | 320 | } |
365 | 321 | ||
366 | if(!rc) { | 322 | if(!rc) { |
@@ -447,36 +403,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
447 | return ERR_PTR(rc); | 403 | return ERR_PTR(rc); |
448 | } | 404 | } |
449 | 405 | ||
450 | int | ||
451 | cifs_dir_open(struct inode *inode, struct file *file) | ||
452 | { /* NB: currently unused since searches are opened in readdir */ | ||
453 | int rc = 0; | ||
454 | int xid; | ||
455 | struct cifs_sb_info *cifs_sb; | ||
456 | struct cifsTconInfo *pTcon; | ||
457 | char *full_path = NULL; | ||
458 | |||
459 | xid = GetXid(); | ||
460 | |||
461 | cifs_sb = CIFS_SB(inode->i_sb); | ||
462 | pTcon = cifs_sb->tcon; | ||
463 | |||
464 | if(file->f_dentry) { | ||
465 | down(&file->f_dentry->d_sb->s_vfs_rename_sem); | ||
466 | full_path = build_wildcard_path_from_dentry(file->f_dentry); | ||
467 | up(&file->f_dentry->d_sb->s_vfs_rename_sem); | ||
468 | } else { | ||
469 | FreeXid(xid); | ||
470 | return -EIO; | ||
471 | } | ||
472 | |||
473 | cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path)); | ||
474 | |||
475 | kfree(full_path); | ||
476 | FreeXid(xid); | ||
477 | return rc; | ||
478 | } | ||
479 | |||
480 | static int | 406 | static int |
481 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | 407 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) |
482 | { | 408 | { |