aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2009-04-08 21:14:32 -0400
committerSteve French <sfrench@us.ibm.com>2009-04-16 21:26:49 -0400
commita6ce4932fbdbcd8f8e8c6df76812014351c32892 (patch)
tree4ffe9ea3379cb3227924491c93960108cf762b96 /fs/cifs/file.c
parentd9fb5c091b419e0495c50c1cce9e4cf9f7105072 (diff)
[CIFS] Add support for posix open during lookup
This patch by utilizing lookup intents, and thus removing a network roundtrip in the open path, improves performance dramatically on open (30% or more) to Samba and other servers which support the cifs posix extensions Signed-off-by: Shirish Pargaonkar <shirishp@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dfd3e6c52a1e..48c9ae09f3d6 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -46,7 +46,7 @@ static inline struct cifsFileInfo *cifs_init_private(
46 memset(private_data, 0, sizeof(struct cifsFileInfo)); 46 memset(private_data, 0, sizeof(struct cifsFileInfo));
47 private_data->netfid = netfid; 47 private_data->netfid = netfid;
48 private_data->pid = current->tgid; 48 private_data->pid = current->tgid;
49 init_MUTEX(&private_data->fh_sem); 49 mutex_init(&private_data->fh_mutex);
50 mutex_init(&private_data->lock_mutex); 50 mutex_init(&private_data->lock_mutex);
51 INIT_LIST_HEAD(&private_data->llist); 51 INIT_LIST_HEAD(&private_data->llist);
52 private_data->pfile = file; /* needed for writepage */ 52 private_data->pfile = file; /* needed for writepage */
@@ -284,35 +284,34 @@ int cifs_open(struct inode *inode, struct file *file)
284 cifs_sb = CIFS_SB(inode->i_sb); 284 cifs_sb = CIFS_SB(inode->i_sb);
285 tcon = cifs_sb->tcon; 285 tcon = cifs_sb->tcon;
286 286
287 if (file->f_flags & O_CREAT) { 287 /* search inode for this file and fill in file->private_data */
288 /* search inode for this file and fill in file->private_data */ 288 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
289 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 289 read_lock(&GlobalSMBSeslock);
290 read_lock(&GlobalSMBSeslock); 290 list_for_each(tmp, &pCifsInode->openFileList) {
291 list_for_each(tmp, &pCifsInode->openFileList) { 291 pCifsFile = list_entry(tmp, struct cifsFileInfo,
292 pCifsFile = list_entry(tmp, struct cifsFileInfo, 292 flist);
293 flist); 293 if ((pCifsFile->pfile == NULL) &&
294 if ((pCifsFile->pfile == NULL) && 294 (pCifsFile->pid == current->tgid)) {
295 (pCifsFile->pid == current->tgid)) { 295 /* mode set in cifs_create */
296 /* mode set in cifs_create */ 296
297 297 /* needed for writepage */
298 /* needed for writepage */ 298 pCifsFile->pfile = file;
299 pCifsFile->pfile = file; 299
300 300 file->private_data = pCifsFile;
301 file->private_data = pCifsFile; 301 break;
302 break;
303 }
304 }
305 read_unlock(&GlobalSMBSeslock);
306 if (file->private_data != NULL) {
307 rc = 0;
308 FreeXid(xid);
309 return rc;
310 } else {
311 if (file->f_flags & O_EXCL)
312 cERROR(1, ("could not find file instance for "
313 "new file %p", file));
314 } 302 }
315 } 303 }
304 read_unlock(&GlobalSMBSeslock);
305
306 if (file->private_data != NULL) {
307 rc = 0;
308 FreeXid(xid);
309 return rc;
310 } else {
311 if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL))
312 cERROR(1, ("could not find file instance for "
313 "new file %p", file));
314 }
316 315
317 full_path = build_path_from_dentry(file->f_path.dentry); 316 full_path = build_path_from_dentry(file->f_path.dentry);
318 if (full_path == NULL) { 317 if (full_path == NULL) {
@@ -500,9 +499,9 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
500 return -EBADF; 499 return -EBADF;
501 500
502 xid = GetXid(); 501 xid = GetXid();
503 down(&pCifsFile->fh_sem); 502 mutex_unlock(&pCifsFile->fh_mutex);
504 if (!pCifsFile->invalidHandle) { 503 if (!pCifsFile->invalidHandle) {
505 up(&pCifsFile->fh_sem); 504 mutex_lock(&pCifsFile->fh_mutex);
506 FreeXid(xid); 505 FreeXid(xid);
507 return 0; 506 return 0;
508 } 507 }
@@ -533,7 +532,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
533 if (full_path == NULL) { 532 if (full_path == NULL) {
534 rc = -ENOMEM; 533 rc = -ENOMEM;
535reopen_error_exit: 534reopen_error_exit:
536 up(&pCifsFile->fh_sem); 535 mutex_lock(&pCifsFile->fh_mutex);
537 FreeXid(xid); 536 FreeXid(xid);
538 return rc; 537 return rc;
539 } 538 }
@@ -575,14 +574,14 @@ reopen_error_exit:
575 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 574 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
576 CIFS_MOUNT_MAP_SPECIAL_CHR); 575 CIFS_MOUNT_MAP_SPECIAL_CHR);
577 if (rc) { 576 if (rc) {
578 up(&pCifsFile->fh_sem); 577 mutex_lock(&pCifsFile->fh_mutex);
579 cFYI(1, ("cifs_open returned 0x%x", rc)); 578 cFYI(1, ("cifs_open returned 0x%x", rc));
580 cFYI(1, ("oplock: %d", oplock)); 579 cFYI(1, ("oplock: %d", oplock));
581 } else { 580 } else {
582reopen_success: 581reopen_success:
583 pCifsFile->netfid = netfid; 582 pCifsFile->netfid = netfid;
584 pCifsFile->invalidHandle = false; 583 pCifsFile->invalidHandle = false;
585 up(&pCifsFile->fh_sem); 584 mutex_lock(&pCifsFile->fh_mutex);
586 pCifsInode = CIFS_I(inode); 585 pCifsInode = CIFS_I(inode);
587 if (pCifsInode) { 586 if (pCifsInode) {
588 if (can_flush) { 587 if (can_flush) {