git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git]
/
fs
/
cifs
/
inode.c
diff --git
a/fs/cifs/inode.c
b/fs/cifs/inode.c
index
d558c30
..
a894e6d
100644
(file)
--- a/
fs/cifs/inode.c
+++ b/
fs/cifs/inode.c
@@
-19,7
+19,6
@@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
-#include <linux/buffer_head.h>
#include <linux/stat.h>
#include <linux/pagemap.h>
#include <asm/div64.h>
#include <linux/stat.h>
#include <linux/pagemap.h>
#include <asm/div64.h>
@@
-319,6
+318,7
@@
int cifs_get_inode_info(struct inode **pinode,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *tmp_path;
char *buf = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *tmp_path;
char *buf = NULL;
+ int adjustTZ = FALSE;
pTcon = cifs_sb->tcon;
cFYI(1,("Getting info on %s", search_path));
pTcon = cifs_sb->tcon;
cFYI(1,("Getting info on %s", search_path));
@@
-338,6
+338,7
@@
int cifs_get_inode_info(struct inode **pinode,
pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
+ 0 /* not legacy */,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* BB optimize code so we do not make the above call
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* BB optimize code so we do not make the above call
@@
-348,6
+349,7
@@
int cifs_get_inode_info(struct inode **pinode,
pfindData, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
pfindData, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
+ adjustTZ = TRUE;
}
}
}
}
@@
-385,8
+387,10
@@
int cifs_get_inode_info(struct inode **pinode,
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
- if (*pinode == NULL)
+ if (*pinode == NULL) {
+ kfree(buf);
return -ENOMEM;
return -ENOMEM;
+ }
/* Is an i_ino of zero legal? Can we use that to check
if the server supports returning inode numbers? Are
there other sanity checks we can use to ensure that
/* Is an i_ino of zero legal? Can we use that to check
if the server supports returning inode numbers? Are
there other sanity checks we can use to ensure that
@@
-432,13
+436,20
@@
int cifs_get_inode_info(struct inode **pinode,
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
/* Linux can not store file creation time so ignore it */
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
/* Linux can not store file creation time so ignore it */
- inode->i_atime =
- cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
+ if(pfindData->LastAccessTime)
+ inode->i_atime = cifs_NTtimeToUnix
+ (le64_to_cpu(pfindData->LastAccessTime));
+ else /* do not need to use current_fs_time - time not stored */
+ inode->i_atime = CURRENT_TIME;
inode->i_mtime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0, ("Attributes came in as 0x%x", attr));
inode->i_mtime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0, ("Attributes came in as 0x%x", attr));
+ if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
+ inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
+ inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
+ }
/* set default mode. will override for dirs below */
if (atomic_read(&cifsInfo->inUse) == 0)
/* set default mode. will override for dirs below */
if (atomic_read(&cifsInfo->inUse) == 0)
@@
-477,6
+488,12
@@
int cifs_get_inode_info(struct inode **pinode,
mode e.g. 555 */
if (cifsInfo->cifsAttrs & ATTR_READONLY)
inode->i_mode &= ~(S_IWUGO);
mode e.g. 555 */
if (cifsInfo->cifsAttrs & ATTR_READONLY)
inode->i_mode &= ~(S_IWUGO);
+ else if ((inode->i_mode & S_IWUGO) == 0)
+ /* the ATTR_READONLY flag may have been */
+ /* changed on server -- set any w bits */
+ /* allowed by mnt_file_mode */
+ inode->i_mode |= (S_IWUGO &
+ cifs_sb->mnt_file_mode);
/* BB add code here -
validate if device or weird share or device type? */
}
/* BB add code here -
validate if device or weird share or device type? */
}
@@
-591,7
+608,7
@@
int cifs_unlink(struct inode *inode, struct dentry *direntry)
if (!rc) {
if (direntry->d_inode)
if (!rc) {
if (direntry->d_inode)
- d
irentry->d_inode->i_nlink--
;
+ d
rop_nlink(direntry->d_inode)
;
} else if (rc == -ENOENT) {
d_drop(direntry);
} else if (rc == -ETXTBSY) {
} else if (rc == -ENOENT) {
d_drop(direntry);
} else if (rc == -ETXTBSY) {
@@
-610,7
+627,7
@@
int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
- d
irentry->d_inode->i_nlink--
;
+ d
rop_nlink(direntry->d_inode)
;
}
} else if (rc == -EACCES) {
/* try only if r/o attribute set in local lookup data? */
}
} else if (rc == -EACCES) {
/* try only if r/o attribute set in local lookup data? */
@@
-664,7
+681,7
@@
int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
if (direntry->d_inode)
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
if (direntry->d_inode)
- d
irentry->d_inode->i_nlink--
;
+ d
rop_nlink(direntry->d_inode)
;
} else if (rc == -ETXTBSY) {
int oplock = FALSE;
__u16 netfid;
} else if (rc == -ETXTBSY) {
int oplock = FALSE;
__u16 netfid;
@@
-685,7
+702,7
@@
int cifs_unlink(struct inode *inode, struct dentry *direntry)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
CIFS_MOUNT_MAP_SPECIAL_CHR);
CIFSSMBClose(xid, pTcon, netfid);
if (direntry->d_inode)
- d
irentry->d_inode->i_nlink--
;
+ d
rop_nlink(direntry->d_inode)
;
}
/* BB if rc = -ETXTBUSY goto the rename logic BB */
}
}
/* BB if rc = -ETXTBUSY goto the rename logic BB */
}
@@
-736,7
+753,7
@@
int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
cFYI(1, ("cifs_mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
cFYI(1, ("cifs_mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
- in
ode->i_nlink++
;
+ in
c_nlink(inode)
;
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid);
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid);
@@
-817,9
+834,9
@@
int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
-
inode->i_nlink--
;
+
drop_nlink(inode)
;
i_size_write(direntry->d_inode,0);
i_size_write(direntry->d_inode,0);
-
direntry->d_inode->i_nlink = 0
;
+
clear_nlink(direntry->d_inode)
;
}
cifsInode = CIFS_I(direntry->d_inode);
}
cifsInode = CIFS_I(direntry->d_inode);
@@
-1122,6
+1139,7
@@
int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
struct cifsFileInfo *open_file = NULL;
FILE_BASIC_INFO time_buf;
int set_time = FALSE;
struct cifsFileInfo *open_file = NULL;
FILE_BASIC_INFO time_buf;
int set_time = FALSE;
+ int set_dosattr = FALSE;
__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
@@
-1258,15
+1276,23
@@
int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
else if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
if ((mode & S_IWUGO) == 0) /* not writeable */ {
else if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
if ((mode & S_IWUGO) == 0) /* not writeable */ {
- if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
+ if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
+ set_dosattr = TRUE;
time_buf.Attributes =
cpu_to_le32(cifsInode->cifsAttrs |
ATTR_READONLY);
time_buf.Attributes =
cpu_to_le32(cifsInode->cifsAttrs |
ATTR_READONLY);
+ }
} else if ((mode & S_IWUGO) == S_IWUGO) {
} else if ((mode & S_IWUGO) == S_IWUGO) {
- if (cifsInode->cifsAttrs & ATTR_READONLY)
+ if (cifsInode->cifsAttrs & ATTR_READONLY) {
+ set_dosattr = TRUE;
time_buf.Attributes =
cpu_to_le32(cifsInode->cifsAttrs &
(~ATTR_READONLY));
time_buf.Attributes =
cpu_to_le32(cifsInode->cifsAttrs &
(~ATTR_READONLY));
+ /* Windows ignores set to zero */
+ if(time_buf.Attributes == 0)
+ time_buf.Attributes |=
+ cpu_to_le32(ATTR_NORMAL);
+ }
}
/* BB to be implemented -
via Windows security descriptors or streams */
}
/* BB to be implemented -
via Windows security descriptors or streams */
@@
-1304,7
+1330,7
@@
int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
} else
time_buf.ChangeTime = 0;
} else
time_buf.ChangeTime = 0;
- if (set_time ||
time_buf.Attributes
) {
+ if (set_time ||
set_dosattr
) {
time_buf.CreationTime = 0; /* do not change */
/* In the future we should experiment - try setting timestamps
via Handle (SetFileInfo) instead of by path */
time_buf.CreationTime = 0; /* do not change */
/* In the future we should experiment - try setting timestamps
via Handle (SetFileInfo) instead of by path */