diff options
author | Jeff Layton <jlayton@redhat.com> | 2010-09-29 19:51:11 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-10-06 12:12:44 -0400 |
commit | 7ffec372458d163492e56e663a1b3a2d7be0a0a2 (patch) | |
tree | e404e3d1000ff41e9b27d0ecb4d6a47187e110d7 /fs/cifs/inode.c | |
parent | f3983c2133e9bea9c8b4f690737d15e3e9b02491 (diff) |
cifs: add refcounted and timestamped container for holding tcons
Eventually, we'll need to track the use of tcons on a per-sb basis, so that
we know when it's ok to tear them down. Begin this conversion by adding a
new "tcon_link" struct and accessors that get it. For now, the core data
structures are untouched -- cifs_sb still just points to a single tcon and
the pointers are just cast to deal with the accessor functions. A later
patch will flesh this out.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 157 |
1 files changed, 122 insertions, 35 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index da716d96dae6..aa229692aef1 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -313,16 +313,21 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
313 | FILE_UNIX_BASIC_INFO find_data; | 313 | FILE_UNIX_BASIC_INFO find_data; |
314 | struct cifs_fattr fattr; | 314 | struct cifs_fattr fattr; |
315 | struct cifsTconInfo *tcon; | 315 | struct cifsTconInfo *tcon; |
316 | struct tcon_link *tlink; | ||
316 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 317 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
317 | 318 | ||
318 | tcon = cifs_sb_tcon(cifs_sb); | ||
319 | |||
320 | cFYI(1, "Getting info on %s", full_path); | 319 | cFYI(1, "Getting info on %s", full_path); |
321 | 320 | ||
321 | tlink = cifs_sb_tlink(cifs_sb); | ||
322 | if (IS_ERR(tlink)) | ||
323 | return PTR_ERR(tlink); | ||
324 | tcon = tlink_tcon(tlink); | ||
325 | |||
322 | /* could have done a find first instead but this returns more info */ | 326 | /* could have done a find first instead but this returns more info */ |
323 | rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, | 327 | rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, |
324 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 328 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
325 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 329 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
330 | cifs_put_tlink(tlink); | ||
326 | 331 | ||
327 | if (!rc) { | 332 | if (!rc) { |
328 | cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); | 333 | cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); |
@@ -361,7 +366,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, | |||
361 | int rc; | 366 | int rc; |
362 | int oplock = 0; | 367 | int oplock = 0; |
363 | __u16 netfid; | 368 | __u16 netfid; |
364 | struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); | 369 | struct tcon_link *tlink; |
370 | struct cifsTconInfo *tcon; | ||
365 | char buf[24]; | 371 | char buf[24]; |
366 | unsigned int bytes_read; | 372 | unsigned int bytes_read; |
367 | char *pbuf; | 373 | char *pbuf; |
@@ -380,7 +386,12 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, | |||
380 | return -EINVAL; /* EOPNOTSUPP? */ | 386 | return -EINVAL; /* EOPNOTSUPP? */ |
381 | } | 387 | } |
382 | 388 | ||
383 | rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, | 389 | tlink = cifs_sb_tlink(cifs_sb); |
390 | if (IS_ERR(tlink)) | ||
391 | return PTR_ERR(tlink); | ||
392 | tcon = tlink_tcon(tlink); | ||
393 | |||
394 | rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ, | ||
384 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 395 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
385 | cifs_sb->local_nls, | 396 | cifs_sb->local_nls, |
386 | cifs_sb->mnt_cifs_flags & | 397 | cifs_sb->mnt_cifs_flags & |
@@ -388,7 +399,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, | |||
388 | if (rc == 0) { | 399 | if (rc == 0) { |
389 | int buf_type = CIFS_NO_BUFFER; | 400 | int buf_type = CIFS_NO_BUFFER; |
390 | /* Read header */ | 401 | /* Read header */ |
391 | rc = CIFSSMBRead(xid, pTcon, netfid, | 402 | rc = CIFSSMBRead(xid, tcon, netfid, |
392 | 24 /* length */, 0 /* offset */, | 403 | 24 /* length */, 0 /* offset */, |
393 | &bytes_read, &pbuf, &buf_type); | 404 | &bytes_read, &pbuf, &buf_type); |
394 | if ((rc == 0) && (bytes_read >= 8)) { | 405 | if ((rc == 0) && (bytes_read >= 8)) { |
@@ -430,8 +441,9 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, | |||
430 | fattr->cf_dtype = DT_REG; | 441 | fattr->cf_dtype = DT_REG; |
431 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | 442 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ |
432 | } | 443 | } |
433 | CIFSSMBClose(xid, pTcon, netfid); | 444 | CIFSSMBClose(xid, tcon, netfid); |
434 | } | 445 | } |
446 | cifs_put_tlink(tlink); | ||
435 | return rc; | 447 | return rc; |
436 | } | 448 | } |
437 | 449 | ||
@@ -449,11 +461,19 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, | |||
449 | ssize_t rc; | 461 | ssize_t rc; |
450 | char ea_value[4]; | 462 | char ea_value[4]; |
451 | __u32 mode; | 463 | __u32 mode; |
464 | struct tcon_link *tlink; | ||
465 | struct cifsTconInfo *tcon; | ||
452 | 466 | ||
453 | rc = CIFSSMBQAllEAs(xid, cifs_sb_tcon(cifs_sb), path, "SETFILEBITS", | 467 | tlink = cifs_sb_tlink(cifs_sb); |
468 | if (IS_ERR(tlink)) | ||
469 | return PTR_ERR(tlink); | ||
470 | tcon = tlink_tcon(tlink); | ||
471 | |||
472 | rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS", | ||
454 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, | 473 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, |
455 | cifs_sb->mnt_cifs_flags & | 474 | cifs_sb->mnt_cifs_flags & |
456 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 475 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
476 | cifs_put_tlink(tlink); | ||
457 | if (rc < 0) | 477 | if (rc < 0) |
458 | return (int)rc; | 478 | return (int)rc; |
459 | else if (rc > 3) { | 479 | else if (rc > 3) { |
@@ -564,26 +584,33 @@ int cifs_get_inode_info(struct inode **pinode, | |||
564 | { | 584 | { |
565 | int rc = 0, tmprc; | 585 | int rc = 0, tmprc; |
566 | struct cifsTconInfo *pTcon; | 586 | struct cifsTconInfo *pTcon; |
587 | struct tcon_link *tlink; | ||
567 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 588 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
568 | char *buf = NULL; | 589 | char *buf = NULL; |
569 | bool adjustTZ = false; | 590 | bool adjustTZ = false; |
570 | struct cifs_fattr fattr; | 591 | struct cifs_fattr fattr; |
571 | 592 | ||
572 | pTcon = cifs_sb_tcon(cifs_sb); | 593 | tlink = cifs_sb_tlink(cifs_sb); |
594 | if (IS_ERR(tlink)) | ||
595 | return PTR_ERR(tlink); | ||
596 | pTcon = tlink_tcon(tlink); | ||
597 | |||
573 | cFYI(1, "Getting info on %s", full_path); | 598 | cFYI(1, "Getting info on %s", full_path); |
574 | 599 | ||
575 | if ((pfindData == NULL) && (*pinode != NULL)) { | 600 | if ((pfindData == NULL) && (*pinode != NULL)) { |
576 | if (CIFS_I(*pinode)->clientCanCacheRead) { | 601 | if (CIFS_I(*pinode)->clientCanCacheRead) { |
577 | cFYI(1, "No need to revalidate cached inode sizes"); | 602 | cFYI(1, "No need to revalidate cached inode sizes"); |
578 | return rc; | 603 | goto cgii_exit; |
579 | } | 604 | } |
580 | } | 605 | } |
581 | 606 | ||
582 | /* if file info not passed in then get it from server */ | 607 | /* if file info not passed in then get it from server */ |
583 | if (pfindData == NULL) { | 608 | if (pfindData == NULL) { |
584 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 609 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
585 | if (buf == NULL) | 610 | if (buf == NULL) { |
586 | return -ENOMEM; | 611 | rc = -ENOMEM; |
612 | goto cgii_exit; | ||
613 | } | ||
587 | pfindData = (FILE_ALL_INFO *)buf; | 614 | pfindData = (FILE_ALL_INFO *)buf; |
588 | 615 | ||
589 | /* could do find first instead but this returns more info */ | 616 | /* could do find first instead but this returns more info */ |
@@ -688,6 +715,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
688 | 715 | ||
689 | cgii_exit: | 716 | cgii_exit: |
690 | kfree(buf); | 717 | kfree(buf); |
718 | cifs_put_tlink(tlink); | ||
691 | return rc; | 719 | return rc; |
692 | } | 720 | } |
693 | 721 | ||
@@ -895,6 +923,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, | |||
895 | struct cifsFileInfo *open_file; | 923 | struct cifsFileInfo *open_file; |
896 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 924 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
897 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 925 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
926 | struct tcon_link *tlink = NULL; | ||
898 | struct cifsTconInfo *pTcon; | 927 | struct cifsTconInfo *pTcon; |
899 | FILE_BASIC_INFO info_buf; | 928 | FILE_BASIC_INFO info_buf; |
900 | 929 | ||
@@ -942,7 +971,13 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, | |||
942 | goto set_via_filehandle; | 971 | goto set_via_filehandle; |
943 | } | 972 | } |
944 | 973 | ||
945 | pTcon = cifs_sb_tcon(cifs_sb); | 974 | tlink = cifs_sb_tlink(cifs_sb); |
975 | if (IS_ERR(tlink)) { | ||
976 | rc = PTR_ERR(tlink); | ||
977 | tlink = NULL; | ||
978 | goto out; | ||
979 | } | ||
980 | pTcon = tlink_tcon(tlink); | ||
946 | 981 | ||
947 | /* | 982 | /* |
948 | * NT4 apparently returns success on this call, but it doesn't | 983 | * NT4 apparently returns success on this call, but it doesn't |
@@ -987,6 +1022,8 @@ set_via_filehandle: | |||
987 | else | 1022 | else |
988 | cifsFileInfo_put(open_file); | 1023 | cifsFileInfo_put(open_file); |
989 | out: | 1024 | out: |
1025 | if (tlink != NULL) | ||
1026 | cifs_put_tlink(tlink); | ||
990 | return rc; | 1027 | return rc; |
991 | } | 1028 | } |
992 | 1029 | ||
@@ -1004,10 +1041,16 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid) | |||
1004 | struct inode *inode = dentry->d_inode; | 1041 | struct inode *inode = dentry->d_inode; |
1005 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 1042 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
1006 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 1043 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1007 | struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); | 1044 | struct tcon_link *tlink; |
1045 | struct cifsTconInfo *tcon; | ||
1008 | __u32 dosattr, origattr; | 1046 | __u32 dosattr, origattr; |
1009 | FILE_BASIC_INFO *info_buf = NULL; | 1047 | FILE_BASIC_INFO *info_buf = NULL; |
1010 | 1048 | ||
1049 | tlink = cifs_sb_tlink(cifs_sb); | ||
1050 | if (IS_ERR(tlink)) | ||
1051 | return PTR_ERR(tlink); | ||
1052 | tcon = tlink_tcon(tlink); | ||
1053 | |||
1011 | rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, | 1054 | rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, |
1012 | DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, | 1055 | DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, |
1013 | &netfid, &oplock, NULL, cifs_sb->local_nls, | 1056 | &netfid, &oplock, NULL, cifs_sb->local_nls, |
@@ -1076,6 +1119,7 @@ out_close: | |||
1076 | CIFSSMBClose(xid, tcon, netfid); | 1119 | CIFSSMBClose(xid, tcon, netfid); |
1077 | out: | 1120 | out: |
1078 | kfree(info_buf); | 1121 | kfree(info_buf); |
1122 | cifs_put_tlink(tlink); | ||
1079 | return rc; | 1123 | return rc; |
1080 | 1124 | ||
1081 | /* | 1125 | /* |
@@ -1115,12 +1159,18 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
1115 | struct cifsInodeInfo *cifs_inode; | 1159 | struct cifsInodeInfo *cifs_inode; |
1116 | struct super_block *sb = dir->i_sb; | 1160 | struct super_block *sb = dir->i_sb; |
1117 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 1161 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1118 | struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); | 1162 | struct tcon_link *tlink; |
1163 | struct cifsTconInfo *tcon; | ||
1119 | struct iattr *attrs = NULL; | 1164 | struct iattr *attrs = NULL; |
1120 | __u32 dosattr = 0, origattr = 0; | 1165 | __u32 dosattr = 0, origattr = 0; |
1121 | 1166 | ||
1122 | cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry); | 1167 | cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry); |
1123 | 1168 | ||
1169 | tlink = cifs_sb_tlink(cifs_sb); | ||
1170 | if (IS_ERR(tlink)) | ||
1171 | return PTR_ERR(tlink); | ||
1172 | tcon = tlink_tcon(tlink); | ||
1173 | |||
1124 | xid = GetXid(); | 1174 | xid = GetXid(); |
1125 | 1175 | ||
1126 | /* Unlink can be called from rename so we can not take the | 1176 | /* Unlink can be called from rename so we can not take the |
@@ -1128,8 +1178,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
1128 | full_path = build_path_from_dentry(dentry); | 1178 | full_path = build_path_from_dentry(dentry); |
1129 | if (full_path == NULL) { | 1179 | if (full_path == NULL) { |
1130 | rc = -ENOMEM; | 1180 | rc = -ENOMEM; |
1131 | FreeXid(xid); | 1181 | goto unlink_out; |
1132 | return rc; | ||
1133 | } | 1182 | } |
1134 | 1183 | ||
1135 | if ((tcon->ses->capabilities & CAP_UNIX) && | 1184 | if ((tcon->ses->capabilities & CAP_UNIX) && |
@@ -1195,10 +1244,11 @@ out_reval: | |||
1195 | dir->i_ctime = dir->i_mtime = current_fs_time(sb); | 1244 | dir->i_ctime = dir->i_mtime = current_fs_time(sb); |
1196 | cifs_inode = CIFS_I(dir); | 1245 | cifs_inode = CIFS_I(dir); |
1197 | CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ | 1246 | CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ |
1198 | 1247 | unlink_out: | |
1199 | kfree(full_path); | 1248 | kfree(full_path); |
1200 | kfree(attrs); | 1249 | kfree(attrs); |
1201 | FreeXid(xid); | 1250 | FreeXid(xid); |
1251 | cifs_put_tlink(tlink); | ||
1202 | return rc; | 1252 | return rc; |
1203 | } | 1253 | } |
1204 | 1254 | ||
@@ -1207,6 +1257,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
1207 | int rc = 0, tmprc; | 1257 | int rc = 0, tmprc; |
1208 | int xid; | 1258 | int xid; |
1209 | struct cifs_sb_info *cifs_sb; | 1259 | struct cifs_sb_info *cifs_sb; |
1260 | struct tcon_link *tlink; | ||
1210 | struct cifsTconInfo *pTcon; | 1261 | struct cifsTconInfo *pTcon; |
1211 | char *full_path = NULL; | 1262 | char *full_path = NULL; |
1212 | struct inode *newinode = NULL; | 1263 | struct inode *newinode = NULL; |
@@ -1214,16 +1265,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
1214 | 1265 | ||
1215 | cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode); | 1266 | cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode); |
1216 | 1267 | ||
1217 | xid = GetXid(); | ||
1218 | |||
1219 | cifs_sb = CIFS_SB(inode->i_sb); | 1268 | cifs_sb = CIFS_SB(inode->i_sb); |
1220 | pTcon = cifs_sb_tcon(cifs_sb); | 1269 | tlink = cifs_sb_tlink(cifs_sb); |
1270 | if (IS_ERR(tlink)) | ||
1271 | return PTR_ERR(tlink); | ||
1272 | pTcon = tlink_tcon(tlink); | ||
1273 | |||
1274 | xid = GetXid(); | ||
1221 | 1275 | ||
1222 | full_path = build_path_from_dentry(direntry); | 1276 | full_path = build_path_from_dentry(direntry); |
1223 | if (full_path == NULL) { | 1277 | if (full_path == NULL) { |
1224 | rc = -ENOMEM; | 1278 | rc = -ENOMEM; |
1225 | FreeXid(xid); | 1279 | goto mkdir_out; |
1226 | return rc; | ||
1227 | } | 1280 | } |
1228 | 1281 | ||
1229 | if ((pTcon->ses->capabilities & CAP_UNIX) && | 1282 | if ((pTcon->ses->capabilities & CAP_UNIX) && |
@@ -1381,6 +1434,7 @@ mkdir_get_info: | |||
1381 | mkdir_out: | 1434 | mkdir_out: |
1382 | kfree(full_path); | 1435 | kfree(full_path); |
1383 | FreeXid(xid); | 1436 | FreeXid(xid); |
1437 | cifs_put_tlink(tlink); | ||
1384 | return rc; | 1438 | return rc; |
1385 | } | 1439 | } |
1386 | 1440 | ||
@@ -1389,6 +1443,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1389 | int rc = 0; | 1443 | int rc = 0; |
1390 | int xid; | 1444 | int xid; |
1391 | struct cifs_sb_info *cifs_sb; | 1445 | struct cifs_sb_info *cifs_sb; |
1446 | struct tcon_link *tlink; | ||
1392 | struct cifsTconInfo *pTcon; | 1447 | struct cifsTconInfo *pTcon; |
1393 | char *full_path = NULL; | 1448 | char *full_path = NULL; |
1394 | struct cifsInodeInfo *cifsInode; | 1449 | struct cifsInodeInfo *cifsInode; |
@@ -1397,18 +1452,23 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1397 | 1452 | ||
1398 | xid = GetXid(); | 1453 | xid = GetXid(); |
1399 | 1454 | ||
1400 | cifs_sb = CIFS_SB(inode->i_sb); | ||
1401 | pTcon = cifs_sb_tcon(cifs_sb); | ||
1402 | |||
1403 | full_path = build_path_from_dentry(direntry); | 1455 | full_path = build_path_from_dentry(direntry); |
1404 | if (full_path == NULL) { | 1456 | if (full_path == NULL) { |
1405 | rc = -ENOMEM; | 1457 | rc = -ENOMEM; |
1406 | FreeXid(xid); | 1458 | goto rmdir_exit; |
1407 | return rc; | 1459 | } |
1460 | |||
1461 | cifs_sb = CIFS_SB(inode->i_sb); | ||
1462 | tlink = cifs_sb_tlink(cifs_sb); | ||
1463 | if (IS_ERR(tlink)) { | ||
1464 | rc = PTR_ERR(tlink); | ||
1465 | goto rmdir_exit; | ||
1408 | } | 1466 | } |
1467 | pTcon = tlink_tcon(tlink); | ||
1409 | 1468 | ||
1410 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1469 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, |
1411 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 1470 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
1471 | cifs_put_tlink(tlink); | ||
1412 | 1472 | ||
1413 | if (!rc) { | 1473 | if (!rc) { |
1414 | drop_nlink(inode); | 1474 | drop_nlink(inode); |
@@ -1429,6 +1489,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1429 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 1489 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = |
1430 | current_fs_time(inode->i_sb); | 1490 | current_fs_time(inode->i_sb); |
1431 | 1491 | ||
1492 | rmdir_exit: | ||
1432 | kfree(full_path); | 1493 | kfree(full_path); |
1433 | FreeXid(xid); | 1494 | FreeXid(xid); |
1434 | return rc; | 1495 | return rc; |
@@ -1439,10 +1500,16 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, | |||
1439 | struct dentry *to_dentry, const char *toPath) | 1500 | struct dentry *to_dentry, const char *toPath) |
1440 | { | 1501 | { |
1441 | struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); | 1502 | struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); |
1442 | struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); | 1503 | struct tcon_link *tlink; |
1504 | struct cifsTconInfo *pTcon; | ||
1443 | __u16 srcfid; | 1505 | __u16 srcfid; |
1444 | int oplock, rc; | 1506 | int oplock, rc; |
1445 | 1507 | ||
1508 | tlink = cifs_sb_tlink(cifs_sb); | ||
1509 | if (IS_ERR(tlink)) | ||
1510 | return PTR_ERR(tlink); | ||
1511 | pTcon = tlink_tcon(tlink); | ||
1512 | |||
1446 | /* try path-based rename first */ | 1513 | /* try path-based rename first */ |
1447 | rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, | 1514 | rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, |
1448 | cifs_sb->mnt_cifs_flags & | 1515 | cifs_sb->mnt_cifs_flags & |
@@ -1454,11 +1521,11 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, | |||
1454 | * rename by filehandle to various Windows servers. | 1521 | * rename by filehandle to various Windows servers. |
1455 | */ | 1522 | */ |
1456 | if (rc == 0 || rc != -ETXTBSY) | 1523 | if (rc == 0 || rc != -ETXTBSY) |
1457 | return rc; | 1524 | goto do_rename_exit; |
1458 | 1525 | ||
1459 | /* open-file renames don't work across directories */ | 1526 | /* open-file renames don't work across directories */ |
1460 | if (to_dentry->d_parent != from_dentry->d_parent) | 1527 | if (to_dentry->d_parent != from_dentry->d_parent) |
1461 | return rc; | 1528 | goto do_rename_exit; |
1462 | 1529 | ||
1463 | /* open the file to be renamed -- we need DELETE perms */ | 1530 | /* open the file to be renamed -- we need DELETE perms */ |
1464 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, | 1531 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, |
@@ -1474,7 +1541,8 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, | |||
1474 | 1541 | ||
1475 | CIFSSMBClose(xid, pTcon, srcfid); | 1542 | CIFSSMBClose(xid, pTcon, srcfid); |
1476 | } | 1543 | } |
1477 | 1544 | do_rename_exit: | |
1545 | cifs_put_tlink(tlink); | ||
1478 | return rc; | 1546 | return rc; |
1479 | } | 1547 | } |
1480 | 1548 | ||
@@ -1484,13 +1552,17 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1484 | char *fromName = NULL; | 1552 | char *fromName = NULL; |
1485 | char *toName = NULL; | 1553 | char *toName = NULL; |
1486 | struct cifs_sb_info *cifs_sb; | 1554 | struct cifs_sb_info *cifs_sb; |
1555 | struct tcon_link *tlink; | ||
1487 | struct cifsTconInfo *tcon; | 1556 | struct cifsTconInfo *tcon; |
1488 | FILE_UNIX_BASIC_INFO *info_buf_source = NULL; | 1557 | FILE_UNIX_BASIC_INFO *info_buf_source = NULL; |
1489 | FILE_UNIX_BASIC_INFO *info_buf_target; | 1558 | FILE_UNIX_BASIC_INFO *info_buf_target; |
1490 | int xid, rc, tmprc; | 1559 | int xid, rc, tmprc; |
1491 | 1560 | ||
1492 | cifs_sb = CIFS_SB(source_dir->i_sb); | 1561 | cifs_sb = CIFS_SB(source_dir->i_sb); |
1493 | tcon = cifs_sb_tcon(cifs_sb); | 1562 | tlink = cifs_sb_tlink(cifs_sb); |
1563 | if (IS_ERR(tlink)) | ||
1564 | return PTR_ERR(tlink); | ||
1565 | tcon = tlink_tcon(tlink); | ||
1494 | 1566 | ||
1495 | xid = GetXid(); | 1567 | xid = GetXid(); |
1496 | 1568 | ||
@@ -1566,6 +1638,7 @@ cifs_rename_exit: | |||
1566 | kfree(fromName); | 1638 | kfree(fromName); |
1567 | kfree(toName); | 1639 | kfree(toName); |
1568 | FreeXid(xid); | 1640 | FreeXid(xid); |
1641 | cifs_put_tlink(tlink); | ||
1569 | return rc; | 1642 | return rc; |
1570 | } | 1643 | } |
1571 | 1644 | ||
@@ -1728,6 +1801,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, | |||
1728 | struct cifsFileInfo *open_file; | 1801 | struct cifsFileInfo *open_file; |
1729 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 1802 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
1730 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 1803 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1804 | struct tcon_link *tlink = NULL; | ||
1731 | struct cifsTconInfo *pTcon = NULL; | 1805 | struct cifsTconInfo *pTcon = NULL; |
1732 | 1806 | ||
1733 | /* | 1807 | /* |
@@ -1758,8 +1832,12 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, | |||
1758 | rc = -EINVAL; | 1832 | rc = -EINVAL; |
1759 | 1833 | ||
1760 | if (rc != 0) { | 1834 | if (rc != 0) { |
1761 | if (pTcon == NULL) | 1835 | if (pTcon == NULL) { |
1762 | pTcon = cifs_sb_tcon(cifs_sb); | 1836 | tlink = cifs_sb_tlink(cifs_sb); |
1837 | if (IS_ERR(tlink)) | ||
1838 | return PTR_ERR(tlink); | ||
1839 | pTcon = tlink_tcon(tlink); | ||
1840 | } | ||
1763 | 1841 | ||
1764 | /* Set file size by pathname rather than by handle | 1842 | /* Set file size by pathname rather than by handle |
1765 | either because no valid, writeable file handle for | 1843 | either because no valid, writeable file handle for |
@@ -1790,6 +1868,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, | |||
1790 | CIFSSMBClose(xid, pTcon, netfid); | 1868 | CIFSSMBClose(xid, pTcon, netfid); |
1791 | } | 1869 | } |
1792 | } | 1870 | } |
1871 | if (tlink) | ||
1872 | cifs_put_tlink(tlink); | ||
1793 | } | 1873 | } |
1794 | 1874 | ||
1795 | if (rc == 0) { | 1875 | if (rc == 0) { |
@@ -1810,6 +1890,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
1810 | struct inode *inode = direntry->d_inode; | 1890 | struct inode *inode = direntry->d_inode; |
1811 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 1891 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
1812 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 1892 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1893 | struct tcon_link *tlink; | ||
1813 | struct cifsTconInfo *pTcon; | 1894 | struct cifsTconInfo *pTcon; |
1814 | struct cifs_unix_set_info_args *args = NULL; | 1895 | struct cifs_unix_set_info_args *args = NULL; |
1815 | struct cifsFileInfo *open_file; | 1896 | struct cifsFileInfo *open_file; |
@@ -1905,11 +1986,17 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
1905 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); | 1986 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
1906 | cifsFileInfo_put(open_file); | 1987 | cifsFileInfo_put(open_file); |
1907 | } else { | 1988 | } else { |
1908 | pTcon = cifs_sb_tcon(cifs_sb); | 1989 | tlink = cifs_sb_tlink(cifs_sb); |
1990 | if (IS_ERR(tlink)) { | ||
1991 | rc = PTR_ERR(tlink); | ||
1992 | goto out; | ||
1993 | } | ||
1994 | pTcon = tlink_tcon(tlink); | ||
1909 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, | 1995 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
1910 | cifs_sb->local_nls, | 1996 | cifs_sb->local_nls, |
1911 | cifs_sb->mnt_cifs_flags & | 1997 | cifs_sb->mnt_cifs_flags & |
1912 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1998 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1999 | cifs_put_tlink(tlink); | ||
1913 | } | 2000 | } |
1914 | 2001 | ||
1915 | if (rc) | 2002 | if (rc) |