aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c11
-rw-r--r--fs/cifs/cifsfs.h7
-rw-r--r--fs/cifs/cifssmb.c30
-rw-r--r--fs/cifs/connect.c18
-rw-r--r--fs/cifs/dir.c448
-rw-r--r--fs/cifs/inode.c5
-rw-r--r--fs/cifs/readdir.c7
-rw-r--r--fs/cifs/transport.c26
8 files changed, 324 insertions, 228 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8b6e344eb0ba..a7610cfedf0a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -257,7 +257,6 @@ cifs_alloc_inode(struct super_block *sb)
257static void cifs_i_callback(struct rcu_head *head) 257static void cifs_i_callback(struct rcu_head *head)
258{ 258{
259 struct inode *inode = container_of(head, struct inode, i_rcu); 259 struct inode *inode = container_of(head, struct inode, i_rcu);
260 INIT_LIST_HEAD(&inode->i_dentry);
261 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); 260 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
262} 261}
263 262
@@ -638,7 +637,10 @@ cifs_do_mount(struct file_system_type *fs_type,
638 mnt_data.cifs_sb = cifs_sb; 637 mnt_data.cifs_sb = cifs_sb;
639 mnt_data.flags = flags; 638 mnt_data.flags = flags;
640 639
641 sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data); 640 /* BB should we make this contingent on mount parm? */
641 flags |= MS_NODIRATIME | MS_NOATIME;
642
643 sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data);
642 if (IS_ERR(sb)) { 644 if (IS_ERR(sb)) {
643 root = ERR_CAST(sb); 645 root = ERR_CAST(sb);
644 cifs_umount(cifs_sb); 646 cifs_umount(cifs_sb);
@@ -649,10 +651,6 @@ cifs_do_mount(struct file_system_type *fs_type,
649 cFYI(1, "Use existing superblock"); 651 cFYI(1, "Use existing superblock");
650 cifs_umount(cifs_sb); 652 cifs_umount(cifs_sb);
651 } else { 653 } else {
652 sb->s_flags = flags;
653 /* BB should we make this contingent on mount parm? */
654 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
655
656 rc = cifs_read_super(sb); 654 rc = cifs_read_super(sb);
657 if (rc) { 655 if (rc) {
658 root = ERR_PTR(rc); 656 root = ERR_PTR(rc);
@@ -778,6 +776,7 @@ struct file_system_type cifs_fs_type = {
778}; 776};
779const struct inode_operations cifs_dir_inode_ops = { 777const struct inode_operations cifs_dir_inode_ops = {
780 .create = cifs_create, 778 .create = cifs_create,
779 .atomic_open = cifs_atomic_open,
781 .lookup = cifs_lookup, 780 .lookup = cifs_lookup,
782 .getattr = cifs_getattr, 781 .getattr = cifs_getattr,
783 .unlink = cifs_unlink, 782 .unlink = cifs_unlink,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 65365358c976..1c49c5a9b27a 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -45,9 +45,12 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf;
45extern const struct inode_operations cifs_dir_inode_ops; 45extern const struct inode_operations cifs_dir_inode_ops;
46extern struct inode *cifs_root_iget(struct super_block *); 46extern struct inode *cifs_root_iget(struct super_block *);
47extern int cifs_create(struct inode *, struct dentry *, umode_t, 47extern int cifs_create(struct inode *, struct dentry *, umode_t,
48 struct nameidata *); 48 bool excl);
49extern int cifs_atomic_open(struct inode *, struct dentry *,
50 struct file *, unsigned, umode_t,
51 int *);
49extern struct dentry *cifs_lookup(struct inode *, struct dentry *, 52extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
50 struct nameidata *); 53 unsigned int);
51extern int cifs_unlink(struct inode *dir, struct dentry *dentry); 54extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
52extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); 55extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
53extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t); 56extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 5b400730c213..4ee522b3f66f 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -86,7 +86,31 @@ static struct {
86#endif /* CONFIG_CIFS_WEAK_PW_HASH */ 86#endif /* CONFIG_CIFS_WEAK_PW_HASH */
87#endif /* CIFS_POSIX */ 87#endif /* CIFS_POSIX */
88 88
89/* Forward declarations */ 89#ifdef CONFIG_HIGHMEM
90/*
91 * On arches that have high memory, kmap address space is limited. By
92 * serializing the kmap operations on those arches, we ensure that we don't
93 * end up with a bunch of threads in writeback with partially mapped page
94 * arrays, stuck waiting for kmap to come back. That situation prevents
95 * progress and can deadlock.
96 */
97static DEFINE_MUTEX(cifs_kmap_mutex);
98
99static inline void
100cifs_kmap_lock(void)
101{
102 mutex_lock(&cifs_kmap_mutex);
103}
104
105static inline void
106cifs_kmap_unlock(void)
107{
108 mutex_unlock(&cifs_kmap_mutex);
109}
110#else /* !CONFIG_HIGHMEM */
111#define cifs_kmap_lock() do { ; } while(0)
112#define cifs_kmap_unlock() do { ; } while(0)
113#endif /* CONFIG_HIGHMEM */
90 114
91/* Mark as invalid, all open files on tree connections since they 115/* Mark as invalid, all open files on tree connections since they
92 were closed when session to server was lost */ 116 were closed when session to server was lost */
@@ -1503,7 +1527,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1503 } 1527 }
1504 1528
1505 /* marshal up the page array */ 1529 /* marshal up the page array */
1530 cifs_kmap_lock();
1506 len = rdata->marshal_iov(rdata, data_len); 1531 len = rdata->marshal_iov(rdata, data_len);
1532 cifs_kmap_unlock();
1507 data_len -= len; 1533 data_len -= len;
1508 1534
1509 /* issue the read if we have any iovecs left to fill */ 1535 /* issue the read if we have any iovecs left to fill */
@@ -2069,7 +2095,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
2069 * and set the iov_len properly for each one. It may also set 2095 * and set the iov_len properly for each one. It may also set
2070 * wdata->bytes too. 2096 * wdata->bytes too.
2071 */ 2097 */
2098 cifs_kmap_lock();
2072 wdata->marshal_iov(iov, wdata); 2099 wdata->marshal_iov(iov, wdata);
2100 cifs_kmap_unlock();
2073 2101
2074 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); 2102 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2075 2103
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0ae86ddf2213..94b7788c3189 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3445,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3445#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) 3445#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
3446#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) 3446#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
3447 3447
3448/*
3449 * On hosts with high memory, we can't currently support wsize/rsize that are
3450 * larger than we can kmap at once. Cap the rsize/wsize at
3451 * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request
3452 * larger than that anyway.
3453 */
3454#ifdef CONFIG_HIGHMEM
3455#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE)
3456#else /* CONFIG_HIGHMEM */
3457#define CIFS_KMAP_SIZE_LIMIT (1<<24)
3458#endif /* CONFIG_HIGHMEM */
3459
3448static unsigned int 3460static unsigned int
3449cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) 3461cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3450{ 3462{
@@ -3475,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3475 wsize = min_t(unsigned int, wsize, 3487 wsize = min_t(unsigned int, wsize,
3476 server->maxBuf - sizeof(WRITE_REQ) + 4); 3488 server->maxBuf - sizeof(WRITE_REQ) + 4);
3477 3489
3490 /* limit to the amount that we can kmap at once */
3491 wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT);
3492
3478 /* hard limit of CIFS_MAX_WSIZE */ 3493 /* hard limit of CIFS_MAX_WSIZE */
3479 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); 3494 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
3480 3495
@@ -3516,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3516 if (!(server->capabilities & CAP_LARGE_READ_X)) 3531 if (!(server->capabilities & CAP_LARGE_READ_X))
3517 rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); 3532 rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
3518 3533
3534 /* limit to the amount that we can kmap at once */
3535 rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT);
3536
3519 /* hard limit of CIFS_MAX_RSIZE */ 3537 /* hard limit of CIFS_MAX_RSIZE */
3520 rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); 3538 rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
3521 3539
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index ec4e9a2a12f8..a180265a10b5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -133,108 +133,141 @@ cifs_bp_rename_retry:
133 return full_path; 133 return full_path;
134} 134}
135 135
136/*
137 * Don't allow the separator character in a path component.
138 * The VFS will not allow "/", but "\" is allowed by posix.
139 */
140static int
141check_name(struct dentry *direntry)
142{
143 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
144 int i;
145
146 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
147 for (i = 0; i < direntry->d_name.len; i++) {
148 if (direntry->d_name.name[i] == '\\') {
149 cFYI(1, "Invalid file name");
150 return -EINVAL;
151 }
152 }
153 }
154 return 0;
155}
156
157
136/* Inode operations in similar order to how they appear in Linux file fs.h */ 158/* Inode operations in similar order to how they appear in Linux file fs.h */
137 159
138int 160static int cifs_do_create(struct inode *inode, struct dentry *direntry,
139cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, 161 int xid, struct tcon_link *tlink, unsigned oflags,
140 struct nameidata *nd) 162 umode_t mode, __u32 *oplock, __u16 *fileHandle,
163 int *created)
141{ 164{
142 int rc = -ENOENT; 165 int rc = -ENOENT;
143 int xid;
144 int create_options = CREATE_NOT_DIR; 166 int create_options = CREATE_NOT_DIR;
145 __u32 oplock = 0; 167 int desiredAccess;
146 int oflags; 168 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
147 /* 169 struct cifs_tcon *tcon = tlink_tcon(tlink);
148 * BB below access is probably too much for mknod to request
149 * but we have to do query and setpathinfo so requesting
150 * less could fail (unless we want to request getatr and setatr
151 * permissions (only). At least for POSIX we do not have to
152 * request so much.
153 */
154 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
155 __u16 fileHandle;
156 struct cifs_sb_info *cifs_sb;
157 struct tcon_link *tlink;
158 struct cifs_tcon *tcon;
159 char *full_path = NULL; 170 char *full_path = NULL;
160 FILE_ALL_INFO *buf = NULL; 171 FILE_ALL_INFO *buf = NULL;
161 struct inode *newinode = NULL; 172 struct inode *newinode = NULL;
162 int disposition = FILE_OVERWRITE_IF; 173 int disposition;
163
164 xid = GetXid();
165
166 cifs_sb = CIFS_SB(inode->i_sb);
167 tlink = cifs_sb_tlink(cifs_sb);
168 if (IS_ERR(tlink)) {
169 FreeXid(xid);
170 return PTR_ERR(tlink);
171 }
172 tcon = tlink_tcon(tlink);
173 174
175 *oplock = 0;
174 if (tcon->ses->server->oplocks) 176 if (tcon->ses->server->oplocks)
175 oplock = REQ_OPLOCK; 177 *oplock = REQ_OPLOCK;
176
177 if (nd)
178 oflags = nd->intent.open.file->f_flags;
179 else
180 oflags = O_RDONLY | O_CREAT;
181 178
182 full_path = build_path_from_dentry(direntry); 179 full_path = build_path_from_dentry(direntry);
183 if (full_path == NULL) { 180 if (full_path == NULL) {
184 rc = -ENOMEM; 181 rc = -ENOMEM;
185 goto cifs_create_out; 182 goto out;
186 } 183 }
187 184
188 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 185 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
186 !tcon->broken_posix_open &&
189 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 187 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
190 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 188 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
191 rc = cifs_posix_open(full_path, &newinode, 189 rc = cifs_posix_open(full_path, &newinode,
192 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); 190 inode->i_sb, mode, oflags, oplock, fileHandle, xid);
193 /* EIO could indicate that (posix open) operation is not 191 switch (rc) {
194 supported, despite what server claimed in capability 192 case 0:
195 negotiation. EREMOTE indicates DFS junction, which is not 193 if (newinode == NULL) {
196 handled in posix open */ 194 /* query inode info */
197
198 if (rc == 0) {
199 if (newinode == NULL) /* query inode info */
200 goto cifs_create_get_file_info; 195 goto cifs_create_get_file_info;
201 else /* success, no need to query */ 196 }
202 goto cifs_create_set_dentry; 197
203 } else if ((rc != -EIO) && (rc != -EREMOTE) && 198 if (!S_ISREG(newinode->i_mode)) {
204 (rc != -EOPNOTSUPP) && (rc != -EINVAL)) 199 /*
205 goto cifs_create_out; 200 * The server may allow us to open things like
206 /* else fallthrough to retry, using older open call, this is 201 * FIFOs, but the client isn't set up to deal
207 case where server does not support this SMB level, and 202 * with that. If it's not a regular file, just
208 falsely claims capability (also get here for DFS case 203 * close it and proceed as if it were a normal
209 which should be rare for path not covered on files) */ 204 * lookup.
210 } 205 */
206 CIFSSMBClose(xid, tcon, *fileHandle);
207 goto cifs_create_get_file_info;
208 }
209 /* success, no need to query */
210 goto cifs_create_set_dentry;
211
212 case -ENOENT:
213 goto cifs_create_get_file_info;
214
215 case -EIO:
216 case -EINVAL:
217 /*
218 * EIO could indicate that (posix open) operation is not
219 * supported, despite what server claimed in capability
220 * negotiation.
221 *
222 * POSIX open in samba versions 3.3.1 and earlier could
223 * incorrectly fail with invalid parameter.
224 */
225 tcon->broken_posix_open = true;
226 break;
227
228 case -EREMOTE:
229 case -EOPNOTSUPP:
230 /*
231 * EREMOTE indicates DFS junction, which is not handled
232 * in posix open. If either that or op not supported
233 * returned, follow the normal lookup.
234 */
235 break;
211 236
212 if (nd) { 237 default:
213 /* if the file is going to stay open, then we 238 goto out;
214 need to set the desired access properly */ 239 }
215 desiredAccess = 0; 240 /*
216 if (OPEN_FMODE(oflags) & FMODE_READ) 241 * fallthrough to retry, using older open call, this is case
217 desiredAccess |= GENERIC_READ; /* is this too little? */ 242 * where server does not support this SMB level, and falsely
218 if (OPEN_FMODE(oflags) & FMODE_WRITE) 243 * claims capability (also get here for DFS case which should be
219 desiredAccess |= GENERIC_WRITE; 244 * rare for path not covered on files)
220 245 */
221 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
222 disposition = FILE_CREATE;
223 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
224 disposition = FILE_OVERWRITE_IF;
225 else if ((oflags & O_CREAT) == O_CREAT)
226 disposition = FILE_OPEN_IF;
227 else
228 cFYI(1, "Create flag not set in create function");
229 } 246 }
230 247
248 desiredAccess = 0;
249 if (OPEN_FMODE(oflags) & FMODE_READ)
250 desiredAccess |= GENERIC_READ; /* is this too little? */
251 if (OPEN_FMODE(oflags) & FMODE_WRITE)
252 desiredAccess |= GENERIC_WRITE;
253
254 disposition = FILE_OVERWRITE_IF;
255 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
256 disposition = FILE_CREATE;
257 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
258 disposition = FILE_OVERWRITE_IF;
259 else if ((oflags & O_CREAT) == O_CREAT)
260 disposition = FILE_OPEN_IF;
261 else
262 cFYI(1, "Create flag not set in create function");
263
231 /* BB add processing to set equivalent of mode - e.g. via CreateX with 264 /* BB add processing to set equivalent of mode - e.g. via CreateX with
232 ACLs */ 265 ACLs */
233 266
234 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 267 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
235 if (buf == NULL) { 268 if (buf == NULL) {
236 rc = -ENOMEM; 269 rc = -ENOMEM;
237 goto cifs_create_out; 270 goto out;
238 } 271 }
239 272
240 /* 273 /*
@@ -250,7 +283,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
250 if (tcon->ses->capabilities & CAP_NT_SMBS) 283 if (tcon->ses->capabilities & CAP_NT_SMBS)
251 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 284 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
252 desiredAccess, create_options, 285 desiredAccess, create_options,
253 &fileHandle, &oplock, buf, cifs_sb->local_nls, 286 fileHandle, oplock, buf, cifs_sb->local_nls,
254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 287 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
255 else 288 else
256 rc = -EIO; /* no NT SMB support fall into legacy open below */ 289 rc = -EIO; /* no NT SMB support fall into legacy open below */
@@ -259,17 +292,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
259 /* old server, retry the open legacy style */ 292 /* old server, retry the open legacy style */
260 rc = SMBLegacyOpen(xid, tcon, full_path, disposition, 293 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
261 desiredAccess, create_options, 294 desiredAccess, create_options,
262 &fileHandle, &oplock, buf, cifs_sb->local_nls, 295 fileHandle, oplock, buf, cifs_sb->local_nls,
263 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 296 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
264 } 297 }
265 if (rc) { 298 if (rc) {
266 cFYI(1, "cifs_create returned 0x%x", rc); 299 cFYI(1, "cifs_create returned 0x%x", rc);
267 goto cifs_create_out; 300 goto out;
268 } 301 }
269 302
270 /* If Open reported that we actually created a file 303 /* If Open reported that we actually created a file
271 then we now have to set the mode if possible */ 304 then we now have to set the mode if possible */
272 if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { 305 if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
273 struct cifs_unix_set_info_args args = { 306 struct cifs_unix_set_info_args args = {
274 .mode = mode, 307 .mode = mode,
275 .ctime = NO_CHANGE_64, 308 .ctime = NO_CHANGE_64,
@@ -278,6 +311,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
278 .device = 0, 311 .device = 0,
279 }; 312 };
280 313
314 *created |= FILE_CREATED;
281 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 315 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
282 args.uid = (__u64) current_fsuid(); 316 args.uid = (__u64) current_fsuid();
283 if (inode->i_mode & S_ISGID) 317 if (inode->i_mode & S_ISGID)
@@ -288,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
288 args.uid = NO_CHANGE_64; 322 args.uid = NO_CHANGE_64;
289 args.gid = NO_CHANGE_64; 323 args.gid = NO_CHANGE_64;
290 } 324 }
291 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle, 325 CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle,
292 current->tgid); 326 current->tgid);
293 } else { 327 } else {
294 /* BB implement mode setting via Windows security 328 /* BB implement mode setting via Windows security
@@ -305,11 +339,11 @@ cifs_create_get_file_info:
305 inode->i_sb, xid); 339 inode->i_sb, xid);
306 else { 340 else {
307 rc = cifs_get_inode_info(&newinode, full_path, buf, 341 rc = cifs_get_inode_info(&newinode, full_path, buf,
308 inode->i_sb, xid, &fileHandle); 342 inode->i_sb, xid, fileHandle);
309 if (newinode) { 343 if (newinode) {
310 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) 344 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
311 newinode->i_mode = mode; 345 newinode->i_mode = mode;
312 if ((oplock & CIFS_CREATE_ACTION) && 346 if ((*oplock & CIFS_CREATE_ACTION) &&
313 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { 347 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
314 newinode->i_uid = current_fsuid(); 348 newinode->i_uid = current_fsuid();
315 if (inode->i_mode & S_ISGID) 349 if (inode->i_mode & S_ISGID)
@@ -321,40 +355,139 @@ cifs_create_get_file_info:
321 } 355 }
322 356
323cifs_create_set_dentry: 357cifs_create_set_dentry:
324 if (rc == 0) 358 if (rc != 0) {
325 d_instantiate(direntry, newinode);
326 else
327 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); 359 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
360 goto out;
361 }
362 d_drop(direntry);
363 d_add(direntry, newinode);
328 364
329 if (newinode && nd) { 365 /* ENOENT for create? How weird... */
330 struct cifsFileInfo *pfile_info; 366 rc = -ENOENT;
331 struct file *filp; 367 if (!newinode) {
368 CIFSSMBClose(xid, tcon, *fileHandle);
369 goto out;
370 }
371 rc = 0;
332 372
333 filp = lookup_instantiate_filp(nd, direntry, generic_file_open); 373out:
334 if (IS_ERR(filp)) { 374 kfree(buf);
335 rc = PTR_ERR(filp); 375 kfree(full_path);
336 CIFSSMBClose(xid, tcon, fileHandle); 376 return rc;
337 goto cifs_create_out; 377}
338 }
339 378
340 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock); 379int
341 if (pfile_info == NULL) { 380cifs_atomic_open(struct inode *inode, struct dentry *direntry,
342 fput(filp); 381 struct file *file, unsigned oflags, umode_t mode,
343 CIFSSMBClose(xid, tcon, fileHandle); 382 int *opened)
344 rc = -ENOMEM; 383{
345 } 384 int rc;
346 } else { 385 int xid;
386 struct tcon_link *tlink;
387 struct cifs_tcon *tcon;
388 __u16 fileHandle;
389 __u32 oplock;
390 struct file *filp;
391 struct cifsFileInfo *pfile_info;
392
393 /* Posix open is only called (at lookup time) for file create now. For
394 * opens (rather than creates), because we do not know if it is a file
395 * or directory yet, and current Samba no longer allows us to do posix
396 * open on dirs, we could end up wasting an open call on what turns out
397 * to be a dir. For file opens, we wait to call posix open till
398 * cifs_open. It could be added to atomic_open in the future but the
399 * performance tradeoff of the extra network request when EISDIR or
400 * EACCES is returned would have to be weighed against the 50% reduction
401 * in network traffic in the other paths.
402 */
403 if (!(oflags & O_CREAT)) {
404 struct dentry *res = cifs_lookup(inode, direntry, 0);
405 if (IS_ERR(res))
406 return PTR_ERR(res);
407
408 return finish_no_open(file, res);
409 }
410
411 rc = check_name(direntry);
412 if (rc)
413 return rc;
414
415 xid = GetXid();
416
417 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
418 inode, direntry->d_name.name, direntry);
419
420 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
421 filp = ERR_CAST(tlink);
422 if (IS_ERR(tlink))
423 goto free_xid;
424
425 tcon = tlink_tcon(tlink);
426
427 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
428 &oplock, &fileHandle, opened);
429
430 if (rc)
431 goto out;
432
433 rc = finish_open(file, direntry, generic_file_open, opened);
434 if (rc) {
347 CIFSSMBClose(xid, tcon, fileHandle); 435 CIFSSMBClose(xid, tcon, fileHandle);
436 goto out;
348 } 437 }
349 438
350cifs_create_out: 439 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
351 kfree(buf); 440 if (pfile_info == NULL) {
352 kfree(full_path); 441 CIFSSMBClose(xid, tcon, fileHandle);
442 fput(filp);
443 rc = -ENOMEM;
444 }
445
446out:
353 cifs_put_tlink(tlink); 447 cifs_put_tlink(tlink);
448free_xid:
354 FreeXid(xid); 449 FreeXid(xid);
355 return rc; 450 return rc;
356} 451}
357 452
453int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
454 bool excl)
455{
456 int rc;
457 int xid = GetXid();
458 /*
459 * BB below access is probably too much for mknod to request
460 * but we have to do query and setpathinfo so requesting
461 * less could fail (unless we want to request getatr and setatr
462 * permissions (only). At least for POSIX we do not have to
463 * request so much.
464 */
465 unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
466 struct tcon_link *tlink;
467 __u16 fileHandle;
468 __u32 oplock;
469 int created = FILE_CREATED;
470
471 cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p",
472 inode, direntry->d_name.name, direntry);
473
474 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
475 rc = PTR_ERR(tlink);
476 if (IS_ERR(tlink))
477 goto free_xid;
478
479 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
480 &oplock, &fileHandle, &created);
481 if (!rc)
482 CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
483
484 cifs_put_tlink(tlink);
485free_xid:
486 FreeXid(xid);
487
488 return rc;
489}
490
358int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, 491int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
359 dev_t device_number) 492 dev_t device_number)
360{ 493{
@@ -488,20 +621,15 @@ mknod_out:
488 621
489struct dentry * 622struct dentry *
490cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, 623cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
491 struct nameidata *nd) 624 unsigned int flags)
492{ 625{
493 int xid; 626 int xid;
494 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 627 int rc = 0; /* to get around spurious gcc warning, set to zero here */
495 __u32 oplock;
496 __u16 fileHandle = 0;
497 bool posix_open = false;
498 struct cifs_sb_info *cifs_sb; 628 struct cifs_sb_info *cifs_sb;
499 struct tcon_link *tlink; 629 struct tcon_link *tlink;
500 struct cifs_tcon *pTcon; 630 struct cifs_tcon *pTcon;
501 struct cifsFileInfo *cfile;
502 struct inode *newInode = NULL; 631 struct inode *newInode = NULL;
503 char *full_path = NULL; 632 char *full_path = NULL;
504 struct file *filp;
505 633
506 xid = GetXid(); 634 xid = GetXid();
507 635
@@ -518,31 +646,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
518 } 646 }
519 pTcon = tlink_tcon(tlink); 647 pTcon = tlink_tcon(tlink);
520 648
521 oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0; 649 rc = check_name(direntry);
522 650 if (rc)
523 /*
524 * Don't allow the separator character in a path component.
525 * The VFS will not allow "/", but "\" is allowed by posix.
526 */
527 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
528 int i;
529 for (i = 0; i < direntry->d_name.len; i++)
530 if (direntry->d_name.name[i] == '\\') {
531 cFYI(1, "Invalid file name");
532 rc = -EINVAL;
533 goto lookup_out;
534 }
535 }
536
537 /*
538 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
539 * the VFS handle the create.
540 */
541 if (nd && (nd->flags & LOOKUP_EXCL)) {
542 d_instantiate(direntry, NULL);
543 rc = 0;
544 goto lookup_out; 651 goto lookup_out;
545 }
546 652
547 /* can not grab the rename sem here since it would 653 /* can not grab the rename sem here since it would
548 deadlock in the cases (beginning of sys_rename itself) 654 deadlock in the cases (beginning of sys_rename itself)
@@ -560,80 +666,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
560 } 666 }
561 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode); 667 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
562 668
563 /* Posix open is only called (at lookup time) for file create now.
564 * For opens (rather than creates), because we do not know if it
565 * is a file or directory yet, and current Samba no longer allows
566 * us to do posix open on dirs, we could end up wasting an open call
567 * on what turns out to be a dir. For file opens, we wait to call posix
568 * open till cifs_open. It could be added here (lookup) in the future
569 * but the performance tradeoff of the extra network request when EISDIR
570 * or EACCES is returned would have to be weighed against the 50%
571 * reduction in network traffic in the other paths.
572 */
573 if (pTcon->unix_ext) { 669 if (pTcon->unix_ext) {
574 if (nd && !(nd->flags & LOOKUP_DIRECTORY) && 670 rc = cifs_get_inode_info_unix(&newInode, full_path,
575 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && 671 parent_dir_inode->i_sb, xid);
576 (nd->intent.open.file->f_flags & O_CREAT)) { 672 } else {
577 rc = cifs_posix_open(full_path, &newInode,
578 parent_dir_inode->i_sb,
579 nd->intent.open.create_mode,
580 nd->intent.open.file->f_flags, &oplock,
581 &fileHandle, xid);
582 /*
583 * The check below works around a bug in POSIX
584 * open in samba versions 3.3.1 and earlier where
585 * open could incorrectly fail with invalid parameter.
586 * If either that or op not supported returned, follow
587 * the normal lookup.
588 */
589 switch (rc) {
590 case 0:
591 /*
592 * The server may allow us to open things like
593 * FIFOs, but the client isn't set up to deal
594 * with that. If it's not a regular file, just
595 * close it and proceed as if it were a normal
596 * lookup.
597 */
598 if (newInode && !S_ISREG(newInode->i_mode)) {
599 CIFSSMBClose(xid, pTcon, fileHandle);
600 break;
601 }
602 case -ENOENT:
603 posix_open = true;
604 case -EOPNOTSUPP:
605 break;
606 default:
607 pTcon->broken_posix_open = true;
608 }
609 }
610 if (!posix_open)
611 rc = cifs_get_inode_info_unix(&newInode, full_path,
612 parent_dir_inode->i_sb, xid);
613 } else
614 rc = cifs_get_inode_info(&newInode, full_path, NULL, 673 rc = cifs_get_inode_info(&newInode, full_path, NULL,
615 parent_dir_inode->i_sb, xid, NULL); 674 parent_dir_inode->i_sb, xid, NULL);
675 }
616 676
617 if ((rc == 0) && (newInode != NULL)) { 677 if ((rc == 0) && (newInode != NULL)) {
618 d_add(direntry, newInode); 678 d_add(direntry, newInode);
619 if (posix_open) {
620 filp = lookup_instantiate_filp(nd, direntry,
621 generic_file_open);
622 if (IS_ERR(filp)) {
623 rc = PTR_ERR(filp);
624 CIFSSMBClose(xid, pTcon, fileHandle);
625 goto lookup_out;
626 }
627
628 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
629 oplock);
630 if (cfile == NULL) {
631 fput(filp);
632 CIFSSMBClose(xid, pTcon, fileHandle);
633 rc = -ENOMEM;
634 goto lookup_out;
635 }
636 }
637 /* since paths are not looked up by component - the parent 679 /* since paths are not looked up by component - the parent
638 directories are presumed to be good here */ 680 directories are presumed to be good here */
639 renew_parental_timestamps(direntry); 681 renew_parental_timestamps(direntry);
@@ -658,9 +700,9 @@ lookup_out:
658} 700}
659 701
660static int 702static int
661cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 703cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
662{ 704{
663 if (nd && (nd->flags & LOOKUP_RCU)) 705 if (flags & LOOKUP_RCU)
664 return -ECHILD; 706 return -ECHILD;
665 707
666 if (direntry->d_inode) { 708 if (direntry->d_inode) {
@@ -689,7 +731,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
689 * This may be nfsd (or something), anyway, we can't see the 731 * This may be nfsd (or something), anyway, we can't see the
690 * intent of this. So, since this can be for creation, drop it. 732 * intent of this. So, since this can be for creation, drop it.
691 */ 733 */
692 if (!nd) 734 if (!flags)
693 return 0; 735 return 0;
694 736
695 /* 737 /*
@@ -697,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
697 * case sensitive name which is specified by user if this is 739 * case sensitive name which is specified by user if this is
698 * for creation. 740 * for creation.
699 */ 741 */
700 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) 742 if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
701 return 0; 743 return 0;
702 744
703 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled) 745 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 745da3d0653e..8e8bb49112ff 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -800,7 +800,7 @@ cifs_find_inode(struct inode *inode, void *opaque)
800 return 0; 800 return 0;
801 801
802 /* if it's not a directory or has no dentries, then flag it */ 802 /* if it's not a directory or has no dentries, then flag it */
803 if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) 803 if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
804 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; 804 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
805 805
806 return 1; 806 return 1;
@@ -825,9 +825,10 @@ static bool
825inode_has_hashed_dentries(struct inode *inode) 825inode_has_hashed_dentries(struct inode *inode)
826{ 826{
827 struct dentry *dentry; 827 struct dentry *dentry;
828 struct hlist_node *p;
828 829
829 spin_lock(&inode->i_lock); 830 spin_lock(&inode->i_lock);
830 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 831 hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
831 if (!d_unhashed(dentry) || IS_ROOT(dentry)) { 832 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
832 spin_unlock(&inode->i_lock); 833 spin_unlock(&inode->i_lock);
833 return true; 834 return true;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 0a8224d1c4c5..a4217f02fab2 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -86,9 +86,12 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
86 86
87 dentry = d_lookup(parent, name); 87 dentry = d_lookup(parent, name);
88 if (dentry) { 88 if (dentry) {
89 /* FIXME: check for inode number changes? */ 89 inode = dentry->d_inode;
90 if (dentry->d_inode != NULL) 90 /* update inode in place if i_ino didn't change */
91 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
92 cifs_fattr_to_inode(inode, fattr);
91 return dentry; 93 return dentry;
94 }
92 d_drop(dentry); 95 d_drop(dentry);
93 dput(dentry); 96 dput(dentry);
94 } 97 }
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 3097ee58fd7d..f25d4ea14be4 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -365,16 +365,14 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov,
365 if (mid == NULL) 365 if (mid == NULL)
366 return -ENOMEM; 366 return -ENOMEM;
367 367
368 /* put it on the pending_mid_q */
369 spin_lock(&GlobalMid_Lock);
370 list_add_tail(&mid->qhead, &server->pending_mid_q);
371 spin_unlock(&GlobalMid_Lock);
372
373 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number); 368 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
374 if (rc) 369 if (rc) {
375 delete_mid(mid); 370 DeleteMidQEntry(mid);
371 return rc;
372 }
373
376 *ret_mid = mid; 374 *ret_mid = mid;
377 return rc; 375 return 0;
378} 376}
379 377
380/* 378/*
@@ -407,17 +405,21 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
407 mid->callback_data = cbdata; 405 mid->callback_data = cbdata;
408 mid->mid_state = MID_REQUEST_SUBMITTED; 406 mid->mid_state = MID_REQUEST_SUBMITTED;
409 407
408 /* put it on the pending_mid_q */
409 spin_lock(&GlobalMid_Lock);
410 list_add_tail(&mid->qhead, &server->pending_mid_q);
411 spin_unlock(&GlobalMid_Lock);
412
413
410 cifs_in_send_inc(server); 414 cifs_in_send_inc(server);
411 rc = smb_sendv(server, iov, nvec); 415 rc = smb_sendv(server, iov, nvec);
412 cifs_in_send_dec(server); 416 cifs_in_send_dec(server);
413 cifs_save_when_sent(mid); 417 cifs_save_when_sent(mid);
414 mutex_unlock(&server->srv_mutex); 418 mutex_unlock(&server->srv_mutex);
415 419
416 if (rc) 420 if (rc == 0)
417 goto out_err; 421 return 0;
418 422
419 return rc;
420out_err:
421 delete_mid(mid); 423 delete_mid(mid);
422 add_credits(server, 1); 424 add_credits(server, 1);
423 wake_up(&server->request_q); 425 wake_up(&server->request_q);