Blame view

fs/cifs/dir.c 19.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   *   fs/cifs/dir.c
   *
   *   vfs operations that deal with dentries
5fdae1f68   Steve French   [CIFS] whitespace...
5
   *
c3b2a0c64   Steve French   [CIFS] improve po...
6
   *   Copyright (C) International Business Machines  Corp., 2002,2009
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   *   the GNU Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  #include <linux/fs.h>
  #include <linux/stat.h>
  #include <linux/slab.h>
  #include <linux/namei.h>
3bc303c25   Jeff Layton   cifs: convert opl...
27
  #include <linux/mount.h>
6ca9f3bae   Jeff Layton   cifs: pass instan...
28
  #include <linux/file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
32
33
34
  #include "cifsfs.h"
  #include "cifspdu.h"
  #include "cifsglob.h"
  #include "cifsproto.h"
  #include "cifs_debug.h"
  #include "cifs_fs_sb.h"
99ee4dbd7   Steve French   [CIFS] Remove som...
35
  static void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
  renew_parental_timestamps(struct dentry *direntry)
  {
5fdae1f68   Steve French   [CIFS] whitespace...
38
39
  	/* BB check if there is a way to get the kernel to do this or if we
  	   really need this */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
  	do {
  		direntry->d_time = jiffies;
  		direntry = direntry->d_parent;
5fdae1f68   Steve French   [CIFS] whitespace...
43
  	} while (!IS_ROOT(direntry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
49
50
  }
  
  /* Note: caller must free return buffer */
  char *
  build_path_from_dentry(struct dentry *direntry)
  {
  	struct dentry *temp;
2fe87f02a   Steve French   [CIFS] Support de...
51
  	int namelen;
646dd5398   Steve French   [CIFS] Fix paths ...
52
  	int dfsplen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  	char *full_path;
88274815f   Steve French   [CIFS] Fix two re...
54
  	char dirsep;
0d424ad0a   Jeff Layton   cifs: add cifs_sb...
55
  	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
96daf2b09   Steve French   [CIFS] Rename thr...
56
  	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
dc137bf55   Al Viro   cifs: build_path_...
57
  	unsigned seq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58

646dd5398   Steve French   [CIFS] Fix paths ...
59
  	dirsep = CIFS_DIR_SEP(cifs_sb);
0d424ad0a   Jeff Layton   cifs: add cifs_sb...
60
61
  	if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
  		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
646dd5398   Steve French   [CIFS] Fix paths ...
62
63
  	else
  		dfsplen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  cifs_bp_rename_retry:
f87d39d95   Steve French   [CIFS] Migrate fr...
65
  	namelen = dfsplen;
dc137bf55   Al Viro   cifs: build_path_...
66
67
  	seq = read_seqbegin(&rename_lock);
  	rcu_read_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
  	for (temp = direntry; !IS_ROOT(temp);) {
  		namelen += (1 + temp->d_name.len);
  		temp = temp->d_parent;
5fdae1f68   Steve French   [CIFS] whitespace...
71
  		if (temp == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
72
  			cERROR(1, "corrupt dentry");
dc137bf55   Al Viro   cifs: build_path_...
73
  			rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
  			return NULL;
  		}
  	}
dc137bf55   Al Viro   cifs: build_path_...
77
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
  
  	full_path = kmalloc(namelen+1, GFP_KERNEL);
5fdae1f68   Steve French   [CIFS] whitespace...
80
  	if (full_path == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
  		return full_path;
  	full_path[namelen] = 0;	/* trailing null */
dc137bf55   Al Viro   cifs: build_path_...
83
  	rcu_read_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	for (temp = direntry; !IS_ROOT(temp);) {
dc137bf55   Al Viro   cifs: build_path_...
85
  		spin_lock(&temp->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
  		namelen -= 1 + temp->d_name.len;
  		if (namelen < 0) {
dc137bf55   Al Viro   cifs: build_path_...
88
  			spin_unlock(&temp->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  			break;
  		} else {
7f57356b7   Steve French   [CIFS] Remove cif...
91
  			full_path[namelen] = dirsep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
  			strncpy(full_path + namelen + 1, temp->d_name.name,
  				temp->d_name.len);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
94
  			cFYI(0, "name: %s", full_path + namelen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
  		}
dc137bf55   Al Viro   cifs: build_path_...
96
  		spin_unlock(&temp->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  		temp = temp->d_parent;
5fdae1f68   Steve French   [CIFS] whitespace...
98
  		if (temp == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
99
  			cERROR(1, "corrupt dentry");
dc137bf55   Al Viro   cifs: build_path_...
100
  			rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
  			kfree(full_path);
  			return NULL;
  		}
  	}
dc137bf55   Al Viro   cifs: build_path_...
105
106
  	rcu_read_unlock();
  	if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
fa71f4470   Jeff Layton   cifs: demote cERR...
107
108
  		cFYI(1, "did not end path lookup where expected. namelen=%d "
  			"dfsplen=%d", namelen, dfsplen);
5fdae1f68   Steve French   [CIFS] whitespace...
109
  		/* presumably this is only possible if racing with a rename
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
  		of one of the parent directories  (we can not lock the dentries
  		above us to prevent this, but retrying should be harmless) */
  		kfree(full_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
  		goto cifs_bp_rename_retry;
  	}
2fe87f02a   Steve French   [CIFS] Support de...
115
116
117
118
119
120
  	/* DIR_SEP already set for byte  0 / vs \ but not for
  	   subsequent slashes in prepath which currently must
  	   be entered the right way - not sure if there is an alternative
  	   since the '\' is a valid posix character so we can not switch
  	   those safely to '/' if any are found in the middle of the prepath */
  	/* BB test paths to Windows with '/' in the midst of prepath */
646dd5398   Steve French   [CIFS] Fix paths ...
121
122
  
  	if (dfsplen) {
0d424ad0a   Jeff Layton   cifs: add cifs_sb...
123
  		strncpy(full_path, tcon->treeName, dfsplen);
646dd5398   Steve French   [CIFS] Fix paths ...
124
125
126
127
128
129
130
131
  		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
  			int i;
  			for (i = 0; i < dfsplen; i++) {
  				if (full_path[i] == '\\')
  					full_path[i] = '/';
  			}
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
  	return full_path;
  }
3979877e5   Steve French   [CIFS] Support fo...
134
  /* Inode operations in similar order to how they appear in Linux file fs.h */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
138
139
140
141
  
  int
  cifs_create(struct inode *inode, struct dentry *direntry, int mode,
  		struct nameidata *nd)
  {
  	int rc = -ENOENT;
  	int xid;
67750fb9e   Jeff Layton   [CIFS] when not u...
142
  	int create_options = CREATE_NOT_DIR;
590a3fe0e   Jeff Layton   cifs: fix oplock ...
143
  	__u32 oplock = 0;
c3b2a0c64   Steve French   [CIFS] improve po...
144
145
146
147
148
149
150
151
  	int oflags;
  	/*
  	 * BB below access is probably too much for mknod to request
  	 *    but we have to do query and setpathinfo so requesting
  	 *    less could fail (unless we want to request getatr and setatr
  	 *    permissions (only).  At least for POSIX we do not have to
  	 *    request so much.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
  	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
  	__u16 fileHandle;
  	struct cifs_sb_info *cifs_sb;
7ffec3724   Jeff Layton   cifs: add refcoun...
155
  	struct tcon_link *tlink;
96daf2b09   Steve French   [CIFS] Rename thr...
156
  	struct cifs_tcon *tcon;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  	char *full_path = NULL;
fb8c4b14d   Steve French   [CIFS] whitespace...
158
  	FILE_ALL_INFO *buf = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  	struct inode *newinode = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  	int disposition = FILE_OVERWRITE_IF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
  
  	xid = GetXid();
  
  	cifs_sb = CIFS_SB(inode->i_sb);
7ffec3724   Jeff Layton   cifs: add refcoun...
165
166
167
168
  	tlink = cifs_sb_tlink(cifs_sb);
  	if (IS_ERR(tlink)) {
  		FreeXid(xid);
  		return PTR_ERR(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  	}
7ffec3724   Jeff Layton   cifs: add refcoun...
170
  	tcon = tlink_tcon(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171

c3b2a0c64   Steve French   [CIFS] improve po...
172
173
  	if (oplockEnabled)
  		oplock = REQ_OPLOCK;
f818dd55c   Steve French   [CIFS] some clean...
174

dd7dd556e   Al Viro   no need to check ...
175
  	if (nd)
608712fe8   Jeff Layton   cifs: fix flags h...
176
  		oflags = nd->intent.open.file->f_flags;
c3b2a0c64   Steve French   [CIFS] improve po...
177
  	else
608712fe8   Jeff Layton   cifs: fix flags h...
178
  		oflags = O_RDONLY | O_CREAT;
c3b2a0c64   Steve French   [CIFS] improve po...
179

7ffec3724   Jeff Layton   cifs: add refcoun...
180
181
182
183
184
  	full_path = build_path_from_dentry(direntry);
  	if (full_path == NULL) {
  		rc = -ENOMEM;
  		goto cifs_create_out;
  	}
c3b2a0c64   Steve French   [CIFS] improve po...
185
186
187
  	if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
  	    (CIFS_UNIX_POSIX_PATH_OPS_CAP &
  			le64_to_cpu(tcon->fsUnixInfo.Capability))) {
fa588e0c5   Steve French   [CIFS] Allow null...
188
  		rc = cifs_posix_open(full_path, &newinode,
fa588e0c5   Steve French   [CIFS] Allow null...
189
  			inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
c3b2a0c64   Steve French   [CIFS] improve po...
190
191
  		/* EIO could indicate that (posix open) operation is not
  		   supported, despite what server claimed in capability
25985edce   Lucas De Marchi   Fix common misspe...
192
  		   negotiation.  EREMOTE indicates DFS junction, which is not
c3b2a0c64   Steve French   [CIFS] improve po...
193
  		   handled in posix open */
90e4ee5d3   Steve French   [CIFS] Fix double...
194
  		if (rc == 0) {
90e4ee5d3   Steve French   [CIFS] Fix double...
195
196
197
198
199
  			if (newinode == NULL) /* query inode info */
  				goto cifs_create_get_file_info;
  			else /* success, no need to query */
  				goto cifs_create_set_dentry;
  		} else if ((rc != -EIO) && (rc != -EREMOTE) &&
703a3b8e5   Steve French   [CIFS] fix posix ...
200
  			 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
c3b2a0c64   Steve French   [CIFS] improve po...
201
202
203
204
205
206
  			goto cifs_create_out;
  		/* else fallthrough to retry, using older open call, this is
  		   case where server does not support this SMB level, and
  		   falsely claims capability (also get here for DFS case
  		   which should be rare for path not covered on files) */
  	}
e08fc0457   Miklos Szeredi   [PATCH] cifs_crea...
207

dd7dd556e   Al Viro   no need to check ...
208
  	if (nd) {
c3b2a0c64   Steve French   [CIFS] improve po...
209
210
  		/* if the file is going to stay open, then we
  		   need to set the desired access properly */
e08fc0457   Miklos Szeredi   [PATCH] cifs_crea...
211
  		desiredAccess = 0;
608712fe8   Jeff Layton   cifs: fix flags h...
212
  		if (OPEN_FMODE(oflags) & FMODE_READ)
c3b2a0c64   Steve French   [CIFS] improve po...
213
  			desiredAccess |= GENERIC_READ; /* is this too little? */
608712fe8   Jeff Layton   cifs: fix flags h...
214
  		if (OPEN_FMODE(oflags) & FMODE_WRITE)
e08fc0457   Miklos Szeredi   [PATCH] cifs_crea...
215
  			desiredAccess |= GENERIC_WRITE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216

5fdae1f68   Steve French   [CIFS] whitespace...
217
  		if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  			disposition = FILE_CREATE;
5fdae1f68   Steve French   [CIFS] whitespace...
219
  		else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  			disposition = FILE_OVERWRITE_IF;
5fdae1f68   Steve French   [CIFS] whitespace...
221
  		else if ((oflags & O_CREAT) == O_CREAT)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  			disposition = FILE_OPEN_IF;
ad7a2926b   Steve French   [CIFS] reduce che...
223
  		else
b6b38f704   Joe Perches   [CIFS] Neaten cER...
224
  			cFYI(1, "Create flag not set in create function");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  	}
5fdae1f68   Steve French   [CIFS] whitespace...
226
227
  	/* BB add processing to set equivalent of mode - e.g. via CreateX with
  	   ACLs */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228

5fdae1f68   Steve French   [CIFS] whitespace...
229
230
  	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
  	if (buf == NULL) {
232341ba7   Jeff Layton   cifs: consolidate...
231
232
  		rc = -ENOMEM;
  		goto cifs_create_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  	}
67750fb9e   Jeff Layton   [CIFS] when not u...
234

67750fb9e   Jeff Layton   [CIFS] when not u...
235
236
237
238
  	/*
  	 * if we're not using unix extensions, see if we need to set
  	 * ATTR_READONLY on the create call
  	 */
f818dd55c   Steve French   [CIFS] some clean...
239
  	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
67750fb9e   Jeff Layton   [CIFS] when not u...
240
  		create_options |= CREATE_OPTION_READONLY;
a6e8a8455   Jeff Layton   cifs: add functio...
241
  	if (tcon->ses->capabilities & CAP_NT_SMBS)
f818dd55c   Steve French   [CIFS] some clean...
242
  		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
67750fb9e   Jeff Layton   [CIFS] when not u...
243
  			 desiredAccess, create_options,
737b758c9   Steve French   [PATCH] cifs: cha...
244
245
  			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
  			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5bafd7659   Steve French   [CIFS] Add suppor...
246
247
  	else
  		rc = -EIO; /* no NT SMB support fall into legacy open below */
5fdae1f68   Steve French   [CIFS] whitespace...
248
  	if (rc == -EIO) {
a9d02ad49   Steve French   [CIFS] Support fo...
249
  		/* old server, retry the open legacy style */
f818dd55c   Steve French   [CIFS] some clean...
250
  		rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
67750fb9e   Jeff Layton   [CIFS] when not u...
251
  			desiredAccess, create_options,
a9d02ad49   Steve French   [CIFS] Support fo...
252
253
  			&fileHandle, &oplock, buf, cifs_sb->local_nls,
  			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5fdae1f68   Steve French   [CIFS] whitespace...
254
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  	if (rc) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
256
  		cFYI(1, "cifs_create returned 0x%x", rc);
c3b2a0c64   Steve French   [CIFS] improve po...
257
258
259
260
261
262
263
  		goto cifs_create_out;
  	}
  
  	/* If Open reported that we actually created a file
  	   then we now have to set the mode if possible */
  	if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
  		struct cifs_unix_set_info_args args = {
4e1e7fb9e   Jeff Layton   bundle up Unix SE...
264
265
266
267
268
  				.mode	= mode,
  				.ctime	= NO_CHANGE_64,
  				.atime	= NO_CHANGE_64,
  				.mtime	= NO_CHANGE_64,
  				.device	= 0,
c3b2a0c64   Steve French   [CIFS] improve po...
269
270
271
272
273
274
275
276
  		};
  
  		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
  			args.uid = (__u64) current_fsuid();
  			if (inode->i_mode & S_ISGID)
  				args.gid = (__u64) inode->i_gid;
  			else
  				args.gid = (__u64) current_fsgid();
3ce53fc4c   Steve French   [CIFS] CIFS shoul...
277
  		} else {
c3b2a0c64   Steve French   [CIFS] improve po...
278
279
  			args.uid = NO_CHANGE_64;
  			args.gid = NO_CHANGE_64;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  		}
d44a9fe2c   Jeff Layton   cifs: switch cifs...
281
282
  		CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
  					current->tgid);
c3b2a0c64   Steve French   [CIFS] improve po...
283
284
285
286
287
288
289
  	} else {
  		/* BB implement mode setting via Windows security
  		   descriptors e.g. */
  		/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
  
  		/* Could set r/o dos attribute if mode & 0222 == 0 */
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290

c3b2a0c64   Steve French   [CIFS] improve po...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  cifs_create_get_file_info:
  	/* server might mask mode so we have to query for it */
  	if (tcon->unix_ext)
  		rc = cifs_get_inode_info_unix(&newinode, full_path,
  					      inode->i_sb, xid);
  	else {
  		rc = cifs_get_inode_info(&newinode, full_path, buf,
  					 inode->i_sb, xid, &fileHandle);
  		if (newinode) {
  			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
  				newinode->i_mode = mode;
  			if ((oplock & CIFS_CREATE_ACTION) &&
  			    (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
  				newinode->i_uid = current_fsuid();
  				if (inode->i_mode & S_ISGID)
  					newinode->i_gid = inode->i_gid;
  				else
  					newinode->i_gid = current_fsgid();
6473a559c   Steve French   [CIFS] Fix missin...
309
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  		}
c3b2a0c64   Steve French   [CIFS] improve po...
311
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312

c3b2a0c64   Steve French   [CIFS] improve po...
313
314
  cifs_create_set_dentry:
  	if (rc == 0)
1c929cfe6   Al Viro   switch cifs
315
  		d_instantiate(direntry, newinode);
c3b2a0c64   Steve French   [CIFS] improve po...
316
  	else
b6b38f704   Joe Perches   [CIFS] Neaten cER...
317
  		cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
c3b2a0c64   Steve French   [CIFS] improve po...
318

dd7dd556e   Al Viro   no need to check ...
319
  	if (newinode && nd) {
fdb360380   Suresh Jayaraman   cifs: propagate c...
320
  		struct cifsFileInfo *pfile_info;
6ca9f3bae   Jeff Layton   cifs: pass instan...
321
322
323
324
325
326
327
328
  		struct file *filp;
  
  		filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
  		if (IS_ERR(filp)) {
  			rc = PTR_ERR(filp);
  			CIFSSMBClose(xid, tcon, fileHandle);
  			goto cifs_create_out;
  		}
abfe1eedd   Jeff Layton   cifs: eliminate t...
329
  		pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
6ca9f3bae   Jeff Layton   cifs: pass instan...
330
331
332
  		if (pfile_info == NULL) {
  			fput(filp);
  			CIFSSMBClose(xid, tcon, fileHandle);
fdb360380   Suresh Jayaraman   cifs: propagate c...
333
  			rc = -ENOMEM;
6ca9f3bae   Jeff Layton   cifs: pass instan...
334
  		}
2422f676f   Jeff Layton   cifs: move cifs_n...
335
336
  	} else {
  		CIFSSMBClose(xid, tcon, fileHandle);
5fdae1f68   Steve French   [CIFS] whitespace...
337
  	}
2422f676f   Jeff Layton   cifs: move cifs_n...
338

d14537f10   Steve French   [PATCH] cifs: rem...
339
340
341
  cifs_create_out:
  	kfree(buf);
  	kfree(full_path);
7ffec3724   Jeff Layton   cifs: add refcoun...
342
  	cifs_put_tlink(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
  	FreeXid(xid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
  	return rc;
  }
5fdae1f68   Steve French   [CIFS] whitespace...
346
347
  int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
  		dev_t device_number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
350
351
  {
  	int rc = -EPERM;
  	int xid;
  	struct cifs_sb_info *cifs_sb;
7ffec3724   Jeff Layton   cifs: add refcoun...
352
  	struct tcon_link *tlink;
96daf2b09   Steve French   [CIFS] Rename thr...
353
  	struct cifs_tcon *pTcon;
fa2989f44   Pavel Shilovsky   CIFS: Use pid sav...
354
  	struct cifs_io_parms io_parms;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
  	char *full_path = NULL;
fb8c4b14d   Steve French   [CIFS] whitespace...
356
  	struct inode *newinode = NULL;
5d9ac7fd3   Jeff Layton   cifs: clean up er...
357
358
359
360
361
  	int oplock = 0;
  	u16 fileHandle;
  	FILE_ALL_INFO *buf = NULL;
  	unsigned int bytes_written;
  	struct win_dev *pdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
  
  	if (!old_valid_dev(device_number))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  	cifs_sb = CIFS_SB(inode->i_sb);
7ffec3724   Jeff Layton   cifs: add refcoun...
366
367
368
369
370
371
372
  	tlink = cifs_sb_tlink(cifs_sb);
  	if (IS_ERR(tlink))
  		return PTR_ERR(tlink);
  
  	pTcon = tlink_tcon(tlink);
  
  	xid = GetXid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  	full_path = build_path_from_dentry(direntry);
5d9ac7fd3   Jeff Layton   cifs: clean up er...
375
  	if (full_path == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  		rc = -ENOMEM;
5d9ac7fd3   Jeff Layton   cifs: clean up er...
377
378
379
380
  		goto mknod_out;
  	}
  
  	if (pTcon->unix_ext) {
4e1e7fb9e   Jeff Layton   bundle up Unix SE...
381
  		struct cifs_unix_set_info_args args = {
ce3b0f8d5   Al Viro   New helper - curr...
382
  			.mode	= mode & ~current_umask(),
4e1e7fb9e   Jeff Layton   bundle up Unix SE...
383
384
385
386
387
  			.ctime	= NO_CHANGE_64,
  			.atime	= NO_CHANGE_64,
  			.mtime	= NO_CHANGE_64,
  			.device	= device_number,
  		};
5fdae1f68   Steve French   [CIFS] whitespace...
388
  		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
a001e5b55   David Howells   CRED: Wrap task c...
389
390
  			args.uid = (__u64) current_fsuid();
  			args.gid = (__u64) current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  		} else {
4e1e7fb9e   Jeff Layton   bundle up Unix SE...
392
393
  			args.uid = NO_CHANGE_64;
  			args.gid = NO_CHANGE_64;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  		}
01ea95e3b   Jeff Layton   cifs: rename CIFS...
395
396
397
398
  		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
  					    cifs_sb->local_nls,
  					    cifs_sb->mnt_cifs_flags &
  						CIFS_MOUNT_MAP_SPECIAL_CHR);
5d9ac7fd3   Jeff Layton   cifs: clean up er...
399
400
  		if (rc)
  			goto mknod_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401

5d9ac7fd3   Jeff Layton   cifs: clean up er...
402
  		rc = cifs_get_inode_info_unix(&newinode, full_path,
5fdae1f68   Steve French   [CIFS] whitespace...
403
  						inode->i_sb, xid);
eda3c0298   Steve French   [CIFS] Add compat...
404

5d9ac7fd3   Jeff Layton   cifs: clean up er...
405
406
407
  		if (rc == 0)
  			d_instantiate(direntry, newinode);
  		goto mknod_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  	}
5d9ac7fd3   Jeff Layton   cifs: clean up er...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
  	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
  		goto mknod_out;
  
  
  	cFYI(1, "sfu compat create special file");
  
  	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
  	if (buf == NULL) {
  		kfree(full_path);
  		rc = -ENOMEM;
  		FreeXid(xid);
  		return rc;
  	}
  
  	/* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
  	rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
  			 GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
  			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
  			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
  	if (rc)
  		goto mknod_out;
  
  	/* BB Do not bother to decode buf since no local inode yet to put
  	 * timestamps in, but we can reuse it safely */
  
  	pdev = (struct win_dev *)buf;
fa2989f44   Pavel Shilovsky   CIFS: Use pid sav...
435
436
437
438
439
  	io_parms.netfid = fileHandle;
  	io_parms.pid = current->tgid;
  	io_parms.tcon = pTcon;
  	io_parms.offset = 0;
  	io_parms.length = sizeof(struct win_dev);
5d9ac7fd3   Jeff Layton   cifs: clean up er...
440
441
442
443
444
445
  	if (S_ISCHR(mode)) {
  		memcpy(pdev->type, "IntxCHR", 8);
  		pdev->major =
  		      cpu_to_le64(MAJOR(device_number));
  		pdev->minor =
  		      cpu_to_le64(MINOR(device_number));
fa2989f44   Pavel Shilovsky   CIFS: Use pid sav...
446
447
  		rc = CIFSSMBWrite(xid, &io_parms,
  			&bytes_written, (char *)pdev,
5d9ac7fd3   Jeff Layton   cifs: clean up er...
448
449
450
451
452
453
454
  			NULL, 0);
  	} else if (S_ISBLK(mode)) {
  		memcpy(pdev->type, "IntxBLK", 8);
  		pdev->major =
  		      cpu_to_le64(MAJOR(device_number));
  		pdev->minor =
  		      cpu_to_le64(MINOR(device_number));
fa2989f44   Pavel Shilovsky   CIFS: Use pid sav...
455
456
  		rc = CIFSSMBWrite(xid, &io_parms,
  			&bytes_written, (char *)pdev,
5d9ac7fd3   Jeff Layton   cifs: clean up er...
457
458
459
460
461
462
463
464
  			NULL, 0);
  	} /* else if (S_ISFIFO) */
  	CIFSSMBClose(xid, pTcon, fileHandle);
  	d_drop(direntry);
  
  	/* FIXME: add code here to set EAs */
  
  mknod_out:
d14537f10   Steve French   [PATCH] cifs: rem...
465
  	kfree(full_path);
5d9ac7fd3   Jeff Layton   cifs: clean up er...
466
  	kfree(buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
  	FreeXid(xid);
7ffec3724   Jeff Layton   cifs: add refcoun...
468
  	cifs_put_tlink(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
  	return rc;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
  struct dentry *
5fdae1f68   Steve French   [CIFS] whitespace...
472
473
  cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
  	    struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
475
476
  {
  	int xid;
  	int rc = 0; /* to get around spurious gcc warning, set to zero here */
590a3fe0e   Jeff Layton   cifs: fix oplock ...
477
  	__u32 oplock = 0;
a6ce4932f   Steve French   [CIFS] Add suppor...
478
479
  	__u16 fileHandle = 0;
  	bool posix_open = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  	struct cifs_sb_info *cifs_sb;
7ffec3724   Jeff Layton   cifs: add refcoun...
481
  	struct tcon_link *tlink;
96daf2b09   Steve French   [CIFS] Rename thr...
482
  	struct cifs_tcon *pTcon;
2422f676f   Jeff Layton   cifs: move cifs_n...
483
  	struct cifsFileInfo *cfile;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
485
  	struct inode *newInode = NULL;
  	char *full_path = NULL;
a6ce4932f   Steve French   [CIFS] Add suppor...
486
  	struct file *filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
  
  	xid = GetXid();
b6b38f704   Joe Perches   [CIFS] Neaten cER...
489
490
  	cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
  	      parent_dir_inode, direntry->d_name.name, direntry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
  	/* check whether path exists */
  
  	cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
7ffec3724   Jeff Layton   cifs: add refcoun...
495
496
497
498
499
500
  	tlink = cifs_sb_tlink(cifs_sb);
  	if (IS_ERR(tlink)) {
  		FreeXid(xid);
  		return (struct dentry *)tlink;
  	}
  	pTcon = tlink_tcon(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501

296034f7d   Steve French   [CIFS] Don't allo...
502
503
504
505
506
507
508
509
  	/*
  	 * Don't allow the separator character in a path component.
  	 * The VFS will not allow "/", but "\" is allowed by posix.
  	 */
  	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
  		int i;
  		for (i = 0; i < direntry->d_name.len; i++)
  			if (direntry->d_name.name[i] == '\\') {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
510
  				cFYI(1, "Invalid file name");
7ffec3724   Jeff Layton   cifs: add refcoun...
511
512
  				rc = -EINVAL;
  				goto lookup_out;
296034f7d   Steve French   [CIFS] Don't allo...
513
514
  			}
  	}
5ddf1e0ff   Jeff Layton   cifs: fix regress...
515
516
517
518
  	/*
  	 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
  	 * the VFS handle the create.
  	 */
8e6c0332d   Steve French   [CIFS] fix oops i...
519
  	if (nd && (nd->flags & LOOKUP_EXCL)) {
5ddf1e0ff   Jeff Layton   cifs: fix regress...
520
  		d_instantiate(direntry, NULL);
7ffec3724   Jeff Layton   cifs: add refcoun...
521
522
  		rc = 0;
  		goto lookup_out;
5ddf1e0ff   Jeff Layton   cifs: fix regress...
523
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
524
525
526
527
  	/* can not grab the rename sem here since it would
  	deadlock in the cases (beginning of sys_rename itself)
  	in which we already have the sb rename sem */
  	full_path = build_path_from_dentry(direntry);
5fdae1f68   Steve French   [CIFS] whitespace...
528
  	if (full_path == NULL) {
7ffec3724   Jeff Layton   cifs: add refcoun...
529
530
  		rc = -ENOMEM;
  		goto lookup_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
533
  	}
  
  	if (direntry->d_inode != NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
534
  		cFYI(1, "non-NULL inode in lookup");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  	} else {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
536
  		cFYI(1, "NULL inode in lookup");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
  	}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
538
  	cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539

8db14ca12   Steve French   [CIFS] Avoid open...
540
541
542
543
544
545
546
547
548
549
  	/* Posix open is only called (at lookup time) for file create now.
  	 * For opens (rather than creates), because we do not know if it
  	 * is a file or directory yet, and current Samba no longer allows
  	 * us to do posix open on dirs, we could end up wasting an open call
  	 * on what turns out to be a dir. For file opens, we wait to call posix
  	 * open till cifs_open.  It could be added here (lookup) in the future
  	 * but the performance tradeoff of the extra network request when EISDIR
  	 * or EACCES is returned would have to be weighed against the 50%
  	 * reduction in network traffic in the other paths.
  	 */
a6ce4932f   Steve French   [CIFS] Add suppor...
550
  	if (pTcon->unix_ext) {
435278038   Al Viro   cifs_lookup(): LO...
551
  		if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
8db14ca12   Steve French   [CIFS] Avoid open...
552
  		     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
608712fe8   Jeff Layton   cifs: fix flags h...
553
  		     (nd->intent.open.file->f_flags & O_CREAT)) {
2422f676f   Jeff Layton   cifs: move cifs_n...
554
  			rc = cifs_posix_open(full_path, &newInode,
fa588e0c5   Steve French   [CIFS] Allow null...
555
  					parent_dir_inode->i_sb,
703a3b8e5   Steve French   [CIFS] fix posix ...
556
  					nd->intent.open.create_mode,
608712fe8   Jeff Layton   cifs: fix flags h...
557
  					nd->intent.open.file->f_flags, &oplock,
a6ce4932f   Steve French   [CIFS] Add suppor...
558
  					&fileHandle, xid);
8db14ca12   Steve French   [CIFS] Avoid open...
559
560
561
562
563
564
565
566
567
568
569
  			/*
  			 * The check below works around a bug in POSIX
  			 * open in samba versions 3.3.1 and earlier where
  			 * open could incorrectly fail with invalid parameter.
  			 * If either that or op not supported returned, follow
  			 * the normal lookup.
  			 */
  			if ((rc == 0) || (rc == -ENOENT))
  				posix_open = true;
  			else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
  				pTcon->broken_posix_open = true;
a6ce4932f   Steve French   [CIFS] Add suppor...
570
571
572
573
574
  		}
  		if (!posix_open)
  			rc = cifs_get_inode_info_unix(&newInode, full_path,
  						parent_dir_inode->i_sb, xid);
  	} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  		rc = cifs_get_inode_info(&newInode, full_path, NULL,
a6ce4932f   Steve French   [CIFS] Add suppor...
576
  				parent_dir_inode->i_sb, xid, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
  
  	if ((rc == 0) && (newInode != NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579
  		d_add(direntry, newInode);
2422f676f   Jeff Layton   cifs: move cifs_n...
580
  		if (posix_open) {
6ca9f3bae   Jeff Layton   cifs: pass instan...
581
582
583
584
585
586
587
  			filp = lookup_instantiate_filp(nd, direntry,
  						       generic_file_open);
  			if (IS_ERR(filp)) {
  				rc = PTR_ERR(filp);
  				CIFSSMBClose(xid, pTcon, fileHandle);
  				goto lookup_out;
  			}
abfe1eedd   Jeff Layton   cifs: eliminate t...
588
589
  			cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
  						  oplock);
2422f676f   Jeff Layton   cifs: move cifs_n...
590
  			if (cfile == NULL) {
6ca9f3bae   Jeff Layton   cifs: pass instan...
591
  				fput(filp);
2422f676f   Jeff Layton   cifs: move cifs_n...
592
593
594
595
  				CIFSSMBClose(xid, pTcon, fileHandle);
  				rc = -ENOMEM;
  				goto lookup_out;
  			}
2422f676f   Jeff Layton   cifs: move cifs_n...
596
  		}
5fdae1f68   Steve French   [CIFS] whitespace...
597
  		/* since paths are not looked up by component - the parent
3abb92722   Steve French   [CIFS] When file ...
598
  		   directories are presumed to be good here */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
601
602
  		renew_parental_timestamps(direntry);
  
  	} else if (rc == -ENOENT) {
  		rc = 0;
3abb92722   Steve French   [CIFS] When file ...
603
  		direntry->d_time = jiffies;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  		d_add(direntry, NULL);
5fdae1f68   Steve French   [CIFS] whitespace...
605
606
  	/*	if it was once a directory (but how can we tell?) we could do
  		shrink_dcache_parent(direntry); */
ed2b91701   Steve French   [CIFS] Do not log...
607
  	} else if (rc != -EACCES) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
608
  		cERROR(1, "Unexpected lookup error %d", rc);
ed2b91701   Steve French   [CIFS] Do not log...
609
610
  		/* We special case check for Access Denied - since that
  		is a common return code */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  	}
2422f676f   Jeff Layton   cifs: move cifs_n...
612
  lookup_out:
d14537f10   Steve French   [PATCH] cifs: rem...
613
  	kfree(full_path);
7ffec3724   Jeff Layton   cifs: add refcoun...
614
  	cifs_put_tlink(tlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
617
  	FreeXid(xid);
  	return ERR_PTR(rc);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
619
620
  static int
  cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
  {
3ca30d40a   Pavel Shilovsky   CIFS: Fix oops wh...
621
  	if (nd && (nd->flags & LOOKUP_RCU))
34286d666   Nick Piggin   fs: rcu-walk awar...
622
  		return -ECHILD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  	if (direntry->d_inode) {
df2cf170c   Jeff Layton   cifs: overhaul ci...
624
  		if (cifs_revalidate_dentry(direntry))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625
  			return 0;
262f86adc   Nick Piggin   cifs: don't overw...
626
627
  		else
  			return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  	}
262f86adc   Nick Piggin   cifs: don't overw...
629
630
631
632
633
634
635
636
637
638
639
640
  	/*
  	 * This may be nfsd (or something), anyway, we can't see the
  	 * intent of this. So, since this can be for creation, drop it.
  	 */
  	if (!nd)
  		return 0;
  
  	/*
  	 * Drop the negative dentry, in order to make sure to use the
  	 * case sensitive name which is specified by user if this is
  	 * for creation.
  	 */
407938e79   Al Viro   LOOKUP_CREATE and...
641
642
  	if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
  		return 0;
262f86adc   Nick Piggin   cifs: don't overw...
643
644
645
646
647
  
  	if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
  		return 0;
  
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
650
651
652
  }
  
  /* static int cifs_d_delete(struct dentry *direntry)
  {
  	int rc = 0;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
653
  	cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
656
  
  	return rc;
  }     */
4fd03e84d   Al Viro   constify dentry_o...
657
  const struct dentry_operations cifs_dentry_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
  	.d_revalidate = cifs_d_revalidate,
01c64feac   David Howells   CIFS: Use d_autom...
659
  	.d_automount = cifs_dfs_d_automount,
5fdae1f68   Steve French   [CIFS] whitespace...
660
  /* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
661
  };
b92327fe6   Steve French   [CIFS] Finish up ...
662

b1e6a015a   Nick Piggin   fs: change d_hash...
663
664
  static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
  		struct qstr *q)
b92327fe6   Steve French   [CIFS] Finish up ...
665
  {
b1e6a015a   Nick Piggin   fs: change d_hash...
666
  	struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
b92327fe6   Steve French   [CIFS] Finish up ...
667
668
669
670
671
672
673
674
675
676
677
  	unsigned long hash;
  	int i;
  
  	hash = init_name_hash();
  	for (i = 0; i < q->len; i++)
  		hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
  					 hash);
  	q->hash = end_name_hash(hash);
  
  	return 0;
  }
621e155a3   Nick Piggin   fs: change d_comp...
678
679
680
681
  static int cifs_ci_compare(const struct dentry *parent,
  		const struct inode *pinode,
  		const struct dentry *dentry, const struct inode *inode,
  		unsigned int len, const char *str, const struct qstr *name)
b92327fe6   Steve French   [CIFS] Finish up ...
682
  {
621e155a3   Nick Piggin   fs: change d_comp...
683
  	struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
b92327fe6   Steve French   [CIFS] Finish up ...
684

621e155a3   Nick Piggin   fs: change d_comp...
685
686
  	if ((name->len == len) &&
  	    (nls_strnicmp(codepage, name->name, str, len) == 0))
b92327fe6   Steve French   [CIFS] Finish up ...
687
  		return 0;
b92327fe6   Steve French   [CIFS] Finish up ...
688
689
  	return 1;
  }
4fd03e84d   Al Viro   constify dentry_o...
690
  const struct dentry_operations cifs_ci_dentry_ops = {
b92327fe6   Steve French   [CIFS] Finish up ...
691
692
693
  	.d_revalidate = cifs_d_revalidate,
  	.d_hash = cifs_ci_hash,
  	.d_compare = cifs_ci_compare,
01c64feac   David Howells   CIFS: Use d_autom...
694
  	.d_automount = cifs_dfs_d_automount,
b92327fe6   Steve French   [CIFS] Finish up ...
695
  };