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.c108
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)
105char *
106build_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
117cifs_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 112BB 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
450int
451cifs_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
480static int 406static int
481cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 407cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
482{ 408{