aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-11-18 14:31:10 -0500
committerSteve French <sfrench@us.ibm.com>2005-11-18 14:31:10 -0500
commit3020a1f58c564e3060ec908c0c4f1b74a12e4280 (patch)
treebc278fcd367cfc23d7670986943403735b7e9a18
parent87c89dd7330735d70cc9912483f6f4c7bc3ff19c (diff)
[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: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/inode.c47
-rw-r--r--fs/cifs/readdir.c31
2 files changed, 56 insertions, 22 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 93dd705577bc..ffc7305841b3 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
41 char *tmp_path; 41 char *tmp_path;
42 42
43 pTcon = cifs_sb->tcon; 43 pTcon = cifs_sb->tcon;
44 cFYI(1, (" Getting info on %s ", search_path)); 44 cFYI(1, ("Getting info on %s ", search_path));
45 /* could have done a find first instead but this returns more info */ 45 /* could have done a find first instead but this returns more info */
46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
111 inode->i_ctime = 111 inode->i_ctime =
112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); 112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
113 inode->i_mode = le64_to_cpu(findData.Permissions); 113 inode->i_mode = le64_to_cpu(findData.Permissions);
114 /* since we set the inode type below we need to mask off
115 to avoid strange results if bits set above */
116 inode->i_mode &= ~S_IFMT;
114 if (type == UNIX_FILE) { 117 if (type == UNIX_FILE) {
115 inode->i_mode |= S_IFREG; 118 inode->i_mode |= S_IFREG;
116 } else if (type == UNIX_SYMLINK) { 119 } else if (type == UNIX_SYMLINK) {
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
129 inode->i_mode |= S_IFIFO; 132 inode->i_mode |= S_IFIFO;
130 } else if (type == UNIX_SOCKET) { 133 } else if (type == UNIX_SOCKET) {
131 inode->i_mode |= S_IFSOCK; 134 inode->i_mode |= S_IFSOCK;
135 } else {
136 /* safest to call it a file if we do not know */
137 inode->i_mode |= S_IFREG;
138 cFYI(1,("unknown type %d",type));
132 } 139 }
133 inode->i_uid = le64_to_cpu(findData.Uid); 140 inode->i_uid = le64_to_cpu(findData.Uid);
134 inode->i_gid = le64_to_cpu(findData.Gid); 141 inode->i_gid = le64_to_cpu(findData.Gid);
@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
228 8 /* length */, 0 /* offset */, 235 8 /* length */, 0 /* offset */,
229 &bytes_read, &pbuf); 236 &bytes_read, &pbuf);
230 if((rc == 0) && (bytes_read == 8)) { 237 if((rc == 0) && (bytes_read == 8)) {
231 cERROR(1,("intx %s" ,pbuf));
232 if(memcmp("IntxBLK", pbuf, 8) == 0) { 238 if(memcmp("IntxBLK", pbuf, 8) == 0) {
233 cFYI(1,("Block device")); 239 cFYI(1,("Block device"));
234 inode->i_mode = S_IFBLK; 240 inode->i_mode |= S_IFBLK;
235 } else if(memcmp("IntxCHR", pbuf, 8) == 0) { 241 } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
236 cFYI(1,("Char device")); 242 cFYI(1,("Char device"));
237 inode->i_mode = S_IFCHR; 243 inode->i_mode |= S_IFCHR;
238 } else if(memcmp("IntxLNK", pbuf, 7) == 0) { 244 } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
239 cFYI(1,("Symlink")); 245 cFYI(1,("Symlink"));
240 inode->i_mode = S_IFLNK; 246 inode->i_mode |= S_IFLNK;
241 } else 247 }
242 inode->i_mode = S_IFREG; /* then it is a file */ 248 } else {
243 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 249 inode->i_mode |= S_IFREG; /* then it is a file */
244 250 rc = -EOPNOTSUPP; /* or some unknown SFU type */
245 } 251 }
246 252
247 CIFSSMBClose(xid, pTcon, netfid); 253 CIFSSMBClose(xid, pTcon, netfid);
@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode,
261 const unsigned char *path, 267 const unsigned char *path,
262 struct cifs_sb_info *cifs_sb, int xid) 268 struct cifs_sb_info *cifs_sb, int xid)
263{ 269{
270#ifdef CONFIG_CIFS_XATTR
264 ssize_t rc; 271 ssize_t rc;
265 char ea_value[4]; 272 char ea_value[4];
266 __u32 mode; 273 __u32 mode;
@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode,
272 return (int)rc; 279 return (int)rc;
273 else if (rc > 3) { 280 else if (rc > 3) {
274 mode = le32_to_cpu(*((__le32 *)ea_value)); 281 mode = le32_to_cpu(*((__le32 *)ea_value));
282 cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
275 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 283 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
276 cFYI(1,("special mode bits 0%o", mode)); 284 cFYI(1,("special mode bits 0%o", mode));
277 return 0; 285 return 0;
278 } else { 286 } else {
279 return 0; 287 return 0;
280 } 288 }
289#else
290 return -EOPNOTSUPP;
291#endif
292
281 293
282} 294}
283 295
@@ -394,9 +406,9 @@ int cifs_get_inode_info(struct inode **pinode,
394 inode = *pinode; 406 inode = *pinode;
395 cifsInfo = CIFS_I(inode); 407 cifsInfo = CIFS_I(inode);
396 cifsInfo->cifsAttrs = attr; 408 cifsInfo->cifsAttrs = attr;
397 cFYI(1, (" Old time %ld ", cifsInfo->time)); 409 cFYI(1, ("Old time %ld ", cifsInfo->time));
398 cifsInfo->time = jiffies; 410 cifsInfo->time = jiffies;
399 cFYI(1, (" New time %ld ", cifsInfo->time)); 411 cFYI(1, ("New time %ld ", cifsInfo->time));
400 412
401 /* blksize needs to be multiple of two. So safer to default to 413 /* blksize needs to be multiple of two. So safer to default to
402 blksize and blkbits set in superblock so 2**blkbits and blksize 414 blksize and blkbits set in superblock so 2**blkbits and blksize
@@ -410,13 +422,15 @@ int cifs_get_inode_info(struct inode **pinode,
410 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 422 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
411 inode->i_ctime = 423 inode->i_ctime =
412 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 424 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
413 cFYI(0, (" Attributes came in as 0x%x ", attr)); 425 cFYI(0, ("Attributes came in as 0x%x ", attr));
414 426
415 /* set default mode. will override for dirs below */ 427 /* set default mode. will override for dirs below */
416 if (atomic_read(&cifsInfo->inUse) == 0) 428 if (atomic_read(&cifsInfo->inUse) == 0)
417 /* new inode, can safely set these fields */ 429 /* new inode, can safely set these fields */
418 inode->i_mode = cifs_sb->mnt_file_mode; 430 inode->i_mode = cifs_sb->mnt_file_mode;
419 431 else /* since we set the inode type below we need to mask off
432 to avoid strange results if type changes and both get orred in */
433 inode->i_mode &= ~S_IFMT;
420/* if (attr & ATTR_REPARSE) */ 434/* if (attr & ATTR_REPARSE) */
421 /* We no longer handle these as symlinks because we could not 435 /* We no longer handle these as symlinks because we could not
422 follow them due to the absolute path with drive letter */ 436 follow them due to the absolute path with drive letter */
@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode,
440 cifs_sb, xid)) { 454 cifs_sb, xid)) {
441 cFYI(1,("Unrecognized sfu inode type")); 455 cFYI(1,("Unrecognized sfu inode type"));
442 } 456 }
457 cFYI(1,("sfu mode 0%o",inode->i_mode));
443 } else { 458 } else {
444 inode->i_mode |= S_IFREG; 459 inode->i_mode |= S_IFREG;
445 /* treat the dos attribute of read-only as read-only 460 /* treat the dos attribute of read-only as read-only
@@ -535,7 +550,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
535 struct cifsInodeInfo *cifsInode; 550 struct cifsInodeInfo *cifsInode;
536 FILE_BASIC_INFO *pinfo_buf; 551 FILE_BASIC_INFO *pinfo_buf;
537 552
538 cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); 553 cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
539 554
540 xid = GetXid(); 555 xid = GetXid();
541 556
@@ -755,7 +770,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
755 char *full_path = NULL; 770 char *full_path = NULL;
756 struct cifsInodeInfo *cifsInode; 771 struct cifsInodeInfo *cifsInode;
757 772
758 cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); 773 cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
759 774
760 xid = GetXid(); 775 xid = GetXid();
761 776
@@ -1074,7 +1089,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1074 1089
1075 xid = GetXid(); 1090 xid = GetXid();
1076 1091
1077 cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1092 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
1078 direntry->d_name.name, attrs->ia_valid)); 1093 direntry->d_name.name, attrs->ia_valid));
1079 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); 1094 cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
1080 pTcon = cifs_sb->tcon; 1095 pTcon = cifs_sb->tcon;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9b7e0ff9584b..9bdaaecae36f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
142 tmp_inode->i_gid = cifs_sb->mnt_gid; 142 tmp_inode->i_gid = cifs_sb->mnt_gid;
143 /* set default mode. will override for dirs below */ 143 /* set default mode. will override for dirs below */
144 tmp_inode->i_mode = cifs_sb->mnt_file_mode; 144 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
145 } else {
146 /* mask off the type bits since it gets set
147 below and we do not want to get two type
148 bits set */
149 tmp_inode->i_mode &= ~S_IFMT;
145 } 150 }
146 151
147 if (attr & ATTR_DIRECTORY) { 152 if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
152 } 157 }
153 tmp_inode->i_mode |= S_IFDIR; 158 tmp_inode->i_mode |= S_IFDIR;
154 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 159 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
155 (attr & ATTR_SYSTEM) && (end_of_file == 0)) { 160 (attr & ATTR_SYSTEM)) {
156 *pobject_type = DT_FIFO; 161 if (end_of_file == 0) {
157 tmp_inode->i_mode |= S_IFIFO; 162 *pobject_type = DT_FIFO;
158/* BB Finish for SFU style symlinks and devies */ 163 tmp_inode->i_mode |= S_IFIFO;
159/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 164 } else {
160 (attr & ATTR_SYSTEM) && ) { */ 165 /* rather than get the type here, we mark the
166 inode as needing revalidate and get the real type
167 (blk vs chr vs. symlink) later ie in lookup */
168 *pobject_type = DT_REG;
169 tmp_inode->i_mode |= S_IFREG;
170 cifsInfo->time = 0;
171 }
161/* we no longer mark these because we could not follow them */ 172/* we no longer mark these because we could not follow them */
162/* } else if (attr & ATTR_REPARSE) { 173/* } else if (attr & ATTR_REPARSE) {
163 *pobject_type = DT_LNK; 174 *pobject_type = DT_LNK;
@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
264 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); 275 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
265 276
266 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 277 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
278 /* since we set the inode type below we need to mask off type
279 to avoid strange results if bits above were corrupt */
280 tmp_inode->i_mode &= ~S_IFMT;
267 if (type == UNIX_FILE) { 281 if (type == UNIX_FILE) {
268 *pobject_type = DT_REG; 282 *pobject_type = DT_REG;
269 tmp_inode->i_mode |= S_IFREG; 283 tmp_inode->i_mode |= S_IFREG;
@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
289 } else if (type == UNIX_SOCKET) { 303 } else if (type == UNIX_SOCKET) {
290 *pobject_type = DT_SOCK; 304 *pobject_type = DT_SOCK;
291 tmp_inode->i_mode |= S_IFSOCK; 305 tmp_inode->i_mode |= S_IFSOCK;
306 } else {
307 /* safest to just call it a file */
308 *pobject_type = DT_REG;
309 tmp_inode->i_mode |= S_IFREG;
310 cFYI(1,("unknown inode type %d",type));
292 } 311 }
293 312
294 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 313 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);