aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifs_dfs_ref.c18
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/dns_resolve.c8
-rw-r--r--fs/cifs/inode.c146
4 files changed, 95 insertions, 81 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 7f8838253410..a1a95b027136 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -74,7 +74,7 @@ static char *cifs_get_share_name(const char *node_name)
74 pSep = memchr(UNC+2, '\\', len-2); 74 pSep = memchr(UNC+2, '\\', len-2);
75 if (!pSep) { 75 if (!pSep) {
76 cERROR(1, ("%s: no server name end in node name: %s", 76 cERROR(1, ("%s: no server name end in node name: %s",
77 __FUNCTION__, node_name)); 77 __func__, node_name));
78 kfree(UNC); 78 kfree(UNC);
79 return NULL; 79 return NULL;
80 } 80 }
@@ -84,7 +84,7 @@ static char *cifs_get_share_name(const char *node_name)
84 pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); 84 pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
85 if (!pSep) { 85 if (!pSep) {
86 cERROR(1, ("%s:2 cant find share name in node name: %s", 86 cERROR(1, ("%s:2 cant find share name in node name: %s",
87 __FUNCTION__, node_name)); 87 __func__, node_name));
88 kfree(UNC); 88 kfree(UNC);
89 return NULL; 89 return NULL;
90 } 90 }
@@ -127,7 +127,7 @@ static char *compose_mount_options(const char *sb_mountdata,
127 rc = dns_resolve_server_name_to_ip(*devname, &srvIP); 127 rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
128 if (rc != 0) { 128 if (rc != 0) {
129 cERROR(1, ("%s: Failed to resolve server part of %s to IP", 129 cERROR(1, ("%s: Failed to resolve server part of %s to IP",
130 __FUNCTION__, *devname)); 130 __func__, *devname));
131 mountdata = ERR_PTR(rc); 131 mountdata = ERR_PTR(rc);
132 goto compose_mount_options_out; 132 goto compose_mount_options_out;
133 } 133 }
@@ -181,8 +181,8 @@ static char *compose_mount_options(const char *sb_mountdata,
181 } 181 }
182 } 182 }
183 183
184 /*cFYI(1,("%s: parent mountdata: %s", __FUNCTION__,sb_mountdata));*/ 184 /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
185 /*cFYI(1, ("%s: submount mountdata: %s", __FUNCTION__, mountdata ));*/ 185 /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/
186 186
187compose_mount_options_out: 187compose_mount_options_out:
188 kfree(srvIP); 188 kfree(srvIP);
@@ -302,7 +302,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
302 int rc = 0; 302 int rc = 0;
303 struct vfsmount *mnt = ERR_PTR(-ENOENT); 303 struct vfsmount *mnt = ERR_PTR(-ENOENT);
304 304
305 cFYI(1, ("in %s", __FUNCTION__)); 305 cFYI(1, ("in %s", __func__));
306 BUG_ON(IS_ROOT(dentry)); 306 BUG_ON(IS_ROOT(dentry));
307 307
308 xid = GetXid(); 308 xid = GetXid();
@@ -336,7 +336,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
336 len = strlen(referrals[i].node_name); 336 len = strlen(referrals[i].node_name);
337 if (len < 2) { 337 if (len < 2) {
338 cERROR(1, ("%s: Net Address path too short: %s", 338 cERROR(1, ("%s: Net Address path too short: %s",
339 __FUNCTION__, referrals[i].node_name)); 339 __func__, referrals[i].node_name));
340 rc = -EINVAL; 340 rc = -EINVAL;
341 goto out_err; 341 goto out_err;
342 } 342 }
@@ -344,7 +344,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
344 nd->path.dentry, 344 nd->path.dentry,
345 referrals[i].node_name); 345 referrals[i].node_name);
346 cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", 346 cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p",
347 __FUNCTION__, 347 __func__,
348 referrals[i].node_name, mnt)); 348 referrals[i].node_name, mnt));
349 349
350 /* complete mount procedure if we accured submount */ 350 /* complete mount procedure if we accured submount */
@@ -365,7 +365,7 @@ out:
365 FreeXid(xid); 365 FreeXid(xid);
366 free_dfs_info_array(referrals, num_referrals); 366 free_dfs_info_array(referrals, num_referrals);
367 kfree(full_path); 367 kfree(full_path);
368 cFYI(1, ("leaving %s" , __FUNCTION__)); 368 cFYI(1, ("leaving %s" , __func__));
369 return ERR_PTR(rc); 369 return ERR_PTR(rc);
370out_err: 370out_err:
371 path_put(&nd->path); 371 path_put(&nd->path);
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0af63e6b426b..a0414bda587c 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -39,8 +39,8 @@ extern int smb_send(struct socket *, struct smb_hdr *,
39 unsigned int /* length */ , struct sockaddr *); 39 unsigned int /* length */ , struct sockaddr *);
40extern unsigned int _GetXid(void); 40extern unsigned int _GetXid(void);
41extern void _FreeXid(unsigned int); 41extern void _FreeXid(unsigned int);
42#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); 42#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid));
43#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} 43#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));}
44extern char *build_path_from_dentry(struct dentry *); 44extern char *build_path_from_dentry(struct dentry *);
45extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 45extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
46/* extern void renew_parental_timestamps(struct dentry *direntry);*/ 46/* extern void renew_parental_timestamps(struct dentry *direntry);*/
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index ef7f43824347..7cc86c418182 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -77,14 +77,14 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
77 /* search for server name delimiter */ 77 /* search for server name delimiter */
78 len = strlen(unc); 78 len = strlen(unc);
79 if (len < 3) { 79 if (len < 3) {
80 cFYI(1, ("%s: unc is too short: %s", __FUNCTION__, unc)); 80 cFYI(1, ("%s: unc is too short: %s", __func__, unc));
81 return -EINVAL; 81 return -EINVAL;
82 } 82 }
83 len -= 2; 83 len -= 2;
84 name = memchr(unc+2, '\\', len); 84 name = memchr(unc+2, '\\', len);
85 if (!name) { 85 if (!name) {
86 cFYI(1, ("%s: probably server name is whole unc: %s", 86 cFYI(1, ("%s: probably server name is whole unc: %s",
87 __FUNCTION__, unc)); 87 __func__, unc));
88 } else { 88 } else {
89 len = (name - unc) - 2/* leading // */; 89 len = (name - unc) - 2/* leading // */;
90 } 90 }
@@ -104,7 +104,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
104 if (*ip_addr) { 104 if (*ip_addr) {
105 memcpy(*ip_addr, rkey->payload.data, len); 105 memcpy(*ip_addr, rkey->payload.data, len);
106 (*ip_addr)[len] = '\0'; 106 (*ip_addr)[len] = '\0';
107 cFYI(1, ("%s: resolved: %s to %s", __FUNCTION__, 107 cFYI(1, ("%s: resolved: %s to %s", __func__,
108 rkey->description, 108 rkey->description,
109 *ip_addr 109 *ip_addr
110 )); 110 ));
@@ -114,7 +114,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
114 } 114 }
115 key_put(rkey); 115 key_put(rkey);
116 } else { 116 } else {
117 cERROR(1, ("%s: unable to resolve: %s", __FUNCTION__, name)); 117 cERROR(1, ("%s: unable to resolve: %s", __func__, name));
118 } 118 }
119 119
120 kfree(name); 120 kfree(name);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 24eb4d392155..e57e5c46ad48 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -30,7 +30,7 @@
30#include "cifs_fs_sb.h" 30#include "cifs_fs_sb.h"
31 31
32 32
33static void cifs_set_ops(struct inode *inode) 33static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
34{ 34{
35 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 35 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
36 36
@@ -57,8 +57,16 @@ static void cifs_set_ops(struct inode *inode)
57 inode->i_data.a_ops = &cifs_addr_ops; 57 inode->i_data.a_ops = &cifs_addr_ops;
58 break; 58 break;
59 case S_IFDIR: 59 case S_IFDIR:
60 inode->i_op = &cifs_dir_inode_ops; 60#ifdef CONFIG_CIFS_DFS_UPCALL
61 inode->i_fop = &cifs_dir_ops; 61 if (is_dfs_referral) {
62 inode->i_op = &cifs_dfs_referral_inode_operations;
63 } else {
64#else /* NO DFS support, treat as a directory */
65 {
66#endif
67 inode->i_op = &cifs_dir_inode_ops;
68 inode->i_fop = &cifs_dir_ops;
69 }
62 break; 70 break;
63 case S_IFLNK: 71 case S_IFLNK:
64 inode->i_op = &cifs_symlink_inode_ops; 72 inode->i_op = &cifs_symlink_inode_ops;
@@ -153,6 +161,30 @@ static void cifs_unix_info_to_inode(struct inode *inode,
153 spin_unlock(&inode->i_lock); 161 spin_unlock(&inode->i_lock);
154} 162}
155 163
164static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon,
165 const char *search_path)
166{
167 int tree_len;
168 int path_len;
169 char *tmp_path;
170
171 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
172 return search_path;
173
174 /* use full path name for working with DFS */
175 tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1);
176 path_len = strnlen(search_path, MAX_PATHCONF);
177
178 tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL);
179 if (tmp_path == NULL)
180 return search_path;
181
182 strncpy(tmp_path, pTcon->treeName, tree_len);
183 strncpy(tmp_path+tree_len, search_path, path_len);
184 tmp_path[tree_len+path_len] = 0;
185 return tmp_path;
186}
187
156int cifs_get_inode_info_unix(struct inode **pinode, 188int cifs_get_inode_info_unix(struct inode **pinode,
157 const unsigned char *search_path, struct super_block *sb, int xid) 189 const unsigned char *search_path, struct super_block *sb, int xid)
158{ 190{
@@ -161,41 +193,28 @@ int cifs_get_inode_info_unix(struct inode **pinode,
161 struct cifsTconInfo *pTcon; 193 struct cifsTconInfo *pTcon;
162 struct inode *inode; 194 struct inode *inode;
163 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 195 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
164 char *tmp_path; 196 const unsigned char *full_path;
197 bool is_dfs_referral = false;
165 198
166 pTcon = cifs_sb->tcon; 199 pTcon = cifs_sb->tcon;
167 cFYI(1, ("Getting info on %s", search_path)); 200 cFYI(1, ("Getting info on %s", search_path));
201
202 full_path = cifs_get_search_path(pTcon, search_path);
203
204try_again_CIFSSMBUnixQPathInfo:
168 /* could have done a find first instead but this returns more info */ 205 /* could have done a find first instead but this returns more info */
169 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 206 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData,
170 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 207 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
171 CIFS_MOUNT_MAP_SPECIAL_CHR); 208 CIFS_MOUNT_MAP_SPECIAL_CHR);
172/* dump_mem("\nUnixQPathInfo return data", &findData, 209/* dump_mem("\nUnixQPathInfo return data", &findData,
173 sizeof(findData)); */ 210 sizeof(findData)); */
174 if (rc) { 211 if (rc) {
175 if (rc == -EREMOTE) { 212 if (rc == -EREMOTE && !is_dfs_referral) {
176 tmp_path = 213 is_dfs_referral = true;
177 kmalloc(strnlen(pTcon->treeName, 214 full_path = search_path;
178 MAX_TREE_SIZE + 1) + 215 goto try_again_CIFSSMBUnixQPathInfo;
179 strnlen(search_path, MAX_PATHCONF) + 1,
180 GFP_KERNEL);
181 if (tmp_path == NULL)
182 return -ENOMEM;
183
184 /* have to skip first of the double backslash of
185 UNC name */
186 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
187 strncat(tmp_path, search_path, MAX_PATHCONF);
188 rc = connect_to_dfs_path(xid, pTcon->ses,
189 /* treename + */ tmp_path,
190 cifs_sb->local_nls,
191 cifs_sb->mnt_cifs_flags &
192 CIFS_MOUNT_MAP_SPECIAL_CHR);
193 kfree(tmp_path);
194
195 /* BB fix up inode etc. */
196 } else if (rc) {
197 return rc;
198 } 216 }
217 goto cgiiu_exit;
199 } else { 218 } else {
200 struct cifsInodeInfo *cifsInfo; 219 struct cifsInodeInfo *cifsInfo;
201 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); 220 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
@@ -204,8 +223,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
204 /* get new inode */ 223 /* get new inode */
205 if (*pinode == NULL) { 224 if (*pinode == NULL) {
206 *pinode = new_inode(sb); 225 *pinode = new_inode(sb);
207 if (*pinode == NULL) 226 if (*pinode == NULL) {
208 return -ENOMEM; 227 rc = -ENOMEM;
228 goto cgiiu_exit;
229 }
209 /* Is an i_ino of zero legal? */ 230 /* Is an i_ino of zero legal? */
210 /* Are there sanity checks we can use to ensure that 231 /* Are there sanity checks we can use to ensure that
211 the server is really filling in that field? */ 232 the server is really filling in that field? */
@@ -237,8 +258,11 @@ int cifs_get_inode_info_unix(struct inode **pinode,
237 (unsigned long) inode->i_size, 258 (unsigned long) inode->i_size,
238 (unsigned long long)inode->i_blocks)); 259 (unsigned long long)inode->i_blocks));
239 260
240 cifs_set_ops(inode); 261 cifs_set_ops(inode, is_dfs_referral);
241 } 262 }
263cgiiu_exit:
264 if (full_path != search_path)
265 kfree(full_path);
242 return rc; 266 return rc;
243} 267}
244 268
@@ -353,9 +377,10 @@ int cifs_get_inode_info(struct inode **pinode,
353 struct cifsTconInfo *pTcon; 377 struct cifsTconInfo *pTcon;
354 struct inode *inode; 378 struct inode *inode;
355 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 379 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
356 char *tmp_path; 380 const unsigned char *full_path = NULL;
357 char *buf = NULL; 381 char *buf = NULL;
358 int adjustTZ = FALSE; 382 int adjustTZ = FALSE;
383 bool is_dfs_referral = false;
359 384
360 pTcon = cifs_sb->tcon; 385 pTcon = cifs_sb->tcon;
361 cFYI(1, ("Getting info on %s", search_path)); 386 cFYI(1, ("Getting info on %s", search_path));
@@ -373,8 +398,12 @@ int cifs_get_inode_info(struct inode **pinode,
373 if (buf == NULL) 398 if (buf == NULL)
374 return -ENOMEM; 399 return -ENOMEM;
375 pfindData = (FILE_ALL_INFO *)buf; 400 pfindData = (FILE_ALL_INFO *)buf;
401
402 full_path = cifs_get_search_path(pTcon, search_path);
403
404try_again_CIFSSMBQPathInfo:
376 /* could do find first instead but this returns more info */ 405 /* could do find first instead but this returns more info */
377 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 406 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
378 0 /* not legacy */, 407 0 /* not legacy */,
379 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 408 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
380 CIFS_MOUNT_MAP_SPECIAL_CHR); 409 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -382,7 +411,7 @@ int cifs_get_inode_info(struct inode **pinode,
382 when server claims no NT SMB support and the above call 411 when server claims no NT SMB support and the above call
383 failed at least once - set flag in tcon or mount */ 412 failed at least once - set flag in tcon or mount */
384 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 413 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
385 rc = SMBQueryInformation(xid, pTcon, search_path, 414 rc = SMBQueryInformation(xid, pTcon, full_path,
386 pfindData, cifs_sb->local_nls, 415 pfindData, cifs_sb->local_nls,
387 cifs_sb->mnt_cifs_flags & 416 cifs_sb->mnt_cifs_flags &
388 CIFS_MOUNT_MAP_SPECIAL_CHR); 417 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -391,31 +420,12 @@ int cifs_get_inode_info(struct inode **pinode,
391 } 420 }
392 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 421 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
393 if (rc) { 422 if (rc) {
394 if (rc == -EREMOTE) { 423 if (rc == -EREMOTE && !is_dfs_referral) {
395 tmp_path = 424 is_dfs_referral = true;
396 kmalloc(strnlen 425 full_path = search_path;
397 (pTcon->treeName, 426 goto try_again_CIFSSMBQPathInfo;
398 MAX_TREE_SIZE + 1) +
399 strnlen(search_path, MAX_PATHCONF) + 1,
400 GFP_KERNEL);
401 if (tmp_path == NULL) {
402 kfree(buf);
403 return -ENOMEM;
404 }
405
406 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
407 strncat(tmp_path, search_path, MAX_PATHCONF);
408 rc = connect_to_dfs_path(xid, pTcon->ses,
409 /* treename + */ tmp_path,
410 cifs_sb->local_nls,
411 cifs_sb->mnt_cifs_flags &
412 CIFS_MOUNT_MAP_SPECIAL_CHR);
413 kfree(tmp_path);
414 /* BB fix up inode etc. */
415 } else if (rc) {
416 kfree(buf);
417 return rc;
418 } 427 }
428 goto cgii_exit;
419 } else { 429 } else {
420 struct cifsInodeInfo *cifsInfo; 430 struct cifsInodeInfo *cifsInfo;
421 __u32 attr = le32_to_cpu(pfindData->Attributes); 431 __u32 attr = le32_to_cpu(pfindData->Attributes);
@@ -424,8 +434,8 @@ int cifs_get_inode_info(struct inode **pinode,
424 if (*pinode == NULL) { 434 if (*pinode == NULL) {
425 *pinode = new_inode(sb); 435 *pinode = new_inode(sb);
426 if (*pinode == NULL) { 436 if (*pinode == NULL) {
427 kfree(buf); 437 rc = -ENOMEM;
428 return -ENOMEM; 438 goto cgii_exit;
429 } 439 }
430 /* Is an i_ino of zero legal? Can we use that to check 440 /* Is an i_ino of zero legal? Can we use that to check
431 if the server supports returning inode numbers? Are 441 if the server supports returning inode numbers? Are
@@ -573,8 +583,11 @@ int cifs_get_inode_info(struct inode **pinode,
573 atomic_set(&cifsInfo->inUse, 1); 583 atomic_set(&cifsInfo->inUse, 1);
574 } 584 }
575 585
576 cifs_set_ops(inode); 586 cifs_set_ops(inode, is_dfs_referral);
577 } 587 }
588cgii_exit:
589 if (full_path != search_path)
590 kfree(full_path);
578 kfree(buf); 591 kfree(buf);
579 return rc; 592 return rc;
580} 593}
@@ -804,7 +817,7 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
804 local_size = tmp_inode->i_size; 817 local_size = tmp_inode->i_size;
805 818
806 cifs_unix_info_to_inode(tmp_inode, pData, 1); 819 cifs_unix_info_to_inode(tmp_inode, pData, 1);
807 cifs_set_ops(tmp_inode); 820 cifs_set_ops(tmp_inode, false);
808 821
809 if (!S_ISREG(tmp_inode->i_mode)) 822 if (!S_ISREG(tmp_inode->i_mode))
810 return; 823 return;
@@ -1407,11 +1420,10 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1407 } 1420 }
1408 cifsInode = CIFS_I(direntry->d_inode); 1421 cifsInode = CIFS_I(direntry->d_inode);
1409 1422
1410 /* BB check if we need to refresh inode from server now ? BB */ 1423 if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
1411
1412 if (attrs->ia_valid & ATTR_SIZE) {
1413 /* 1424 /*
1414 Flush data before changing file size on server. If the 1425 Flush data before changing file size or changing the last
1426 write time of the file on the server. If the
1415 flush returns error, store it to report later and continue. 1427 flush returns error, store it to report later and continue.
1416 BB: This should be smarter. Why bother flushing pages that 1428 BB: This should be smarter. Why bother flushing pages that
1417 will be truncated anyway? Also, should we error out here if 1429 will be truncated anyway? Also, should we error out here if
@@ -1422,7 +1434,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1422 CIFS_I(direntry->d_inode)->write_behind_rc = rc; 1434 CIFS_I(direntry->d_inode)->write_behind_rc = rc;
1423 rc = 0; 1435 rc = 0;
1424 } 1436 }
1437 }
1425 1438
1439 if (attrs->ia_valid & ATTR_SIZE) {
1426 /* To avoid spurious oplock breaks from server, in the case of 1440 /* To avoid spurious oplock breaks from server, in the case of
1427 inodes that we already have open, avoid doing path based 1441 inodes that we already have open, avoid doing path based
1428 setting of file size if we can do it by handle. 1442 setting of file size if we can do it by handle.