提交 3020a1f5 编写于 作者: S Steve French

[CIFS] Fix scheduling while atomic when pending writes at file close time

Fix the case in which readdir reset file type when SFU mount option
specified.

Also fix sfu related functions to not request EAs (xattrs) when not
configured in Kconfig
Signed-off-by: NSteve French <sfrench@us.ibm.com>
上级 87c89dd7
...@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
char *tmp_path; char *tmp_path;
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
cFYI(1, (" Getting info on %s ", search_path)); cFYI(1, ("Getting info on %s ", search_path));
/* could have done a find first instead but this returns more info */ /* could have done a find first instead but this returns more info */
rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
...@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_ctime = inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
inode->i_mode = le64_to_cpu(findData.Permissions); inode->i_mode = le64_to_cpu(findData.Permissions);
/* since we set the inode type below we need to mask off
to avoid strange results if bits set above */
inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) { if (type == UNIX_FILE) {
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
} else if (type == UNIX_SYMLINK) { } else if (type == UNIX_SYMLINK) {
...@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_mode |= S_IFIFO; inode->i_mode |= S_IFIFO;
} else if (type == UNIX_SOCKET) { } else if (type == UNIX_SOCKET) {
inode->i_mode |= S_IFSOCK; inode->i_mode |= S_IFSOCK;
} else {
/* safest to call it a file if we do not know */
inode->i_mode |= S_IFREG;
cFYI(1,("unknown type %d",type));
} }
inode->i_uid = le64_to_cpu(findData.Uid); inode->i_uid = le64_to_cpu(findData.Uid);
inode->i_gid = le64_to_cpu(findData.Gid); inode->i_gid = le64_to_cpu(findData.Gid);
...@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, ...@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
8 /* length */, 0 /* offset */, 8 /* length */, 0 /* offset */,
&bytes_read, &pbuf); &bytes_read, &pbuf);
if((rc == 0) && (bytes_read == 8)) { if((rc == 0) && (bytes_read == 8)) {
cERROR(1,("intx %s" ,pbuf));
if(memcmp("IntxBLK", pbuf, 8) == 0) { if(memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1,("Block device")); cFYI(1,("Block device"));
inode->i_mode = S_IFBLK; inode->i_mode |= S_IFBLK;
} else if(memcmp("IntxCHR", pbuf, 8) == 0) { } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
cFYI(1,("Char device")); cFYI(1,("Char device"));
inode->i_mode = S_IFCHR; inode->i_mode |= S_IFCHR;
} else if(memcmp("IntxLNK", pbuf, 7) == 0) { } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
cFYI(1,("Symlink")); cFYI(1,("Symlink"));
inode->i_mode = S_IFLNK; inode->i_mode |= S_IFLNK;
} else }
inode->i_mode = S_IFREG; /* then it is a file */ } else {
rc = -EOPNOTSUPP; /* or some unknown SFU type */ inode->i_mode |= S_IFREG; /* then it is a file */
rc = -EOPNOTSUPP; /* or some unknown SFU type */
} }
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
...@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode, ...@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode,
const unsigned char *path, const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid) struct cifs_sb_info *cifs_sb, int xid)
{ {
#ifdef CONFIG_CIFS_XATTR
ssize_t rc; ssize_t rc;
char ea_value[4]; char ea_value[4];
__u32 mode; __u32 mode;
...@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode, ...@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode,
return (int)rc; return (int)rc;
else if (rc > 3) { else if (rc > 3) {
mode = le32_to_cpu(*((__le32 *)ea_value)); mode = le32_to_cpu(*((__le32 *)ea_value));
cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
cFYI(1,("special mode bits 0%o", mode)); cFYI(1,("special mode bits 0%o", mode));
return 0; return 0;
} else { } else {
return 0; return 0;
} }
#else
return -EOPNOTSUPP;
#endif
} }
...@@ -394,9 +406,9 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -394,9 +406,9 @@ int cifs_get_inode_info(struct inode **pinode,
inode = *pinode; inode = *pinode;
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
cifsInfo->cifsAttrs = attr; cifsInfo->cifsAttrs = attr;
cFYI(1, (" Old time %ld ", cifsInfo->time)); cFYI(1, ("Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, ("New time %ld ", cifsInfo->time));
/* blksize needs to be multiple of two. So safer to default to /* blksize needs to be multiple of two. So safer to default to
blksize and blkbits set in superblock so 2**blkbits and blksize blksize and blkbits set in superblock so 2**blkbits and blksize
...@@ -410,13 +422,15 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -410,13 +422,15 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime = inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0, (" Attributes came in as 0x%x ", attr)); cFYI(0, ("Attributes came in as 0x%x ", attr));
/* set default mode. will override for dirs below */ /* set default mode. will override for dirs below */
if (atomic_read(&cifsInfo->inUse) == 0) if (atomic_read(&cifsInfo->inUse) == 0)
/* new inode, can safely set these fields */ /* new inode, can safely set these fields */
inode->i_mode = cifs_sb->mnt_file_mode; inode->i_mode = cifs_sb->mnt_file_mode;
else /* since we set the inode type below we need to mask off
to avoid strange results if type changes and both get orred in */
inode->i_mode &= ~S_IFMT;
/* if (attr & ATTR_REPARSE) */ /* if (attr & ATTR_REPARSE) */
/* We no longer handle these as symlinks because we could not /* We no longer handle these as symlinks because we could not
follow them due to the absolute path with drive letter */ follow them due to the absolute path with drive letter */
...@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_sb, xid)) { cifs_sb, xid)) {
cFYI(1,("Unrecognized sfu inode type")); cFYI(1,("Unrecognized sfu inode type"));
} }
cFYI(1,("sfu mode 0%o",inode->i_mode));
} else { } else {
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
/* treat the dos attribute of read-only as read-only /* treat the dos attribute of read-only as read-only
...@@ -535,7 +550,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -535,7 +550,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
FILE_BASIC_INFO *pinfo_buf; FILE_BASIC_INFO *pinfo_buf;
cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -755,7 +770,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) ...@@ -755,7 +770,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
char *full_path = NULL; char *full_path = NULL;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -1074,7 +1089,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -1074,7 +1089,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
xid = GetXid(); xid = GetXid();
cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
direntry->d_name.name, attrs->ia_valid)); direntry->d_name.name, attrs->ia_valid));
cifs_sb = CIFS_SB(direntry->d_inode->i_sb); cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
......
...@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode, ...@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_gid = cifs_sb->mnt_gid; tmp_inode->i_gid = cifs_sb->mnt_gid;
/* set default mode. will override for dirs below */ /* set default mode. will override for dirs below */
tmp_inode->i_mode = cifs_sb->mnt_file_mode; tmp_inode->i_mode = cifs_sb->mnt_file_mode;
} else {
/* mask off the type bits since it gets set
below and we do not want to get two type
bits set */
tmp_inode->i_mode &= ~S_IFMT;
} }
if (attr & ATTR_DIRECTORY) { if (attr & ATTR_DIRECTORY) {
...@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode, ...@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
} }
tmp_inode->i_mode |= S_IFDIR; tmp_inode->i_mode |= S_IFDIR;
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(attr & ATTR_SYSTEM) && (end_of_file == 0)) { (attr & ATTR_SYSTEM)) {
*pobject_type = DT_FIFO; if (end_of_file == 0) {
tmp_inode->i_mode |= S_IFIFO; *pobject_type = DT_FIFO;
/* BB Finish for SFU style symlinks and devies */ tmp_inode->i_mode |= S_IFIFO;
/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && } else {
(attr & ATTR_SYSTEM) && ) { */ /* rather than get the type here, we mark the
inode as needing revalidate and get the real type
(blk vs chr vs. symlink) later ie in lookup */
*pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG;
cifsInfo->time = 0;
}
/* we no longer mark these because we could not follow them */ /* we no longer mark these because we could not follow them */
/* } else if (attr & ATTR_REPARSE) { /* } else if (attr & ATTR_REPARSE) {
*pobject_type = DT_LNK; *pobject_type = DT_LNK;
...@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode, ...@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
/* since we set the inode type below we need to mask off type
to avoid strange results if bits above were corrupt */
tmp_inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) { if (type == UNIX_FILE) {
*pobject_type = DT_REG; *pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG; tmp_inode->i_mode |= S_IFREG;
...@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, ...@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
} else if (type == UNIX_SOCKET) { } else if (type == UNIX_SOCKET) {
*pobject_type = DT_SOCK; *pobject_type = DT_SOCK;
tmp_inode->i_mode |= S_IFSOCK; tmp_inode->i_mode |= S_IFSOCK;
} else {
/* safest to just call it a file */
*pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG;
cFYI(1,("unknown inode type %d",type));
} }
tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册