Commit 62bbc304 authored by Steve French's avatar Steve French Committed by Steve French

Handle rename of hardlinked files properly (treat as a noop)

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent e3e741aa
Version 1.18
------------
Do not rename hardlinked files (since that should be a noop). Flush
cached write behind data when reopening a file after session abend.
Version 1.17 Version 1.17
------------ ------------
Update number of blocks in file so du command is happier (in Linux a fake Update number of blocks in file so du command is happier (in Linux a fake
......
...@@ -209,7 +209,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, ...@@ -209,7 +209,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
length += item_length; length += item_length;
buf += item_length; buf += item_length;
item_length = sprintf(buf, item_length = sprintf(buf,
"%d sessions and %d shares reconnected after failure\n", "%d session %d share reconnects\n",
tcpSesReconnectCount.counter,tconInfoReconnectCount.counter); tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
length += item_length; length += item_length;
buf += item_length; buf += item_length;
......
...@@ -93,5 +93,5 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *, ...@@ -93,5 +93,5 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
size_t, int); size_t, int);
extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
#define CIFS_VERSION "1.17" #define CIFS_VERSION "1.18"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -568,9 +568,38 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, ...@@ -568,9 +568,38 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
rc = CIFSSMBRename(xid, pTcon, fromName, toName, rc = CIFSSMBRename(xid, pTcon, fromName, toName,
cifs_sb_source->local_nls); cifs_sb_source->local_nls);
if(rc == -EEXIST) { if(rc == -EEXIST) {
cifs_unlink(target_inode, target_direntry); /* check if they are the same file
rc = CIFSSMBRename(xid, pTcon, fromName, toName, because rename of hardlinked files is a noop */
cifs_sb_source->local_nls); FILE_UNIX_BASIC_INFO * info_buf_source;
FILE_UNIX_BASIC_INFO * info_buf_target;
info_buf_source =
kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL);
if(info_buf_source != NULL) {
info_buf_target = info_buf_source+1;
rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
info_buf_source, cifs_sb_source->local_nls);
if(rc == 0) {
rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName,
info_buf_target,
cifs_sb_target->local_nls);
}
if((rc == 0) &&
(info_buf_source->UniqueId ==
info_buf_target->UniqueId)) {
/* do not rename since the files are hardlinked
which is a noop */
} else {
/* we either can not tell the files are hardlinked
(as with Windows servers) or files are not hardlinked
so delete the target manually before renaming to
follow POSIX rather than Windows semantics */
cifs_unlink(target_inode, target_direntry);
rc = CIFSSMBRename(xid, pTcon, fromName, toName,
cifs_sb_source->local_nls);
}
kfree(info_buf_source);
} /* if we can not get memory just leave rc as EEXIST */
} }
if((rc == -EIO)||(rc == -EEXIST)) { if((rc == -EIO)||(rc == -EEXIST)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment