aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-04-30 16:13:06 -0400
committerSteve French <sfrench@us.ibm.com>2007-04-30 16:13:06 -0400
commit4523cc3044d1bc7fcf3d7fee75d62bc76b8e1abb (patch)
tree31c2b6c0a81f14ec812d09586eb8ef5a586743cb /fs/cifs/inode.c
parent984acfe1cfb613257a15f30b3cf60ae7e4ed8f06 (diff)
[CIFS] UID/GID override on CIFS mounts to Samba
When CIFS Unix Extensions are negotiated we get the Unix uid and gid owners of the file from the server (on the Unix Query Path Info levels), but if the server's uids don't match the client uid's users were having to disable the Unix Extensions (which turned off features they still wanted). The changeset patch allows users to override uid and/or gid for file/directory owner with a default uid and/or gid specified at mount (as is often done when mounting from Linux cifs client to Windows server). This changeset also displays the uid and gid used by default in /proc/mounts (if applicable). Also cleans up code by adding some of the missing spaces after "if" keywords per-kernel style guidelines (as suggested by Randy Dunlap when he reviewed the patch). Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c55
1 files changed, 33 insertions, 22 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f74f37cee119..3e87dad3367c 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -90,7 +90,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
90 (*pinode)->i_ino = 90 (*pinode)->i_ino =
91 (unsigned long)findData.UniqueId; 91 (unsigned long)findData.UniqueId;
92 } /* note ino incremented to unique num in new_inode */ 92 } /* note ino incremented to unique num in new_inode */
93 if(sb->s_flags & MS_NOATIME) 93 if (sb->s_flags & MS_NOATIME)
94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
95 95
96 insert_inode_hash(*pinode); 96 insert_inode_hash(*pinode);
@@ -139,8 +139,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
139 inode->i_mode |= S_IFREG; 139 inode->i_mode |= S_IFREG;
140 cFYI(1,("unknown type %d",type)); 140 cFYI(1,("unknown type %d",type));
141 } 141 }
142 inode->i_uid = le64_to_cpu(findData.Uid); 142
143 inode->i_gid = le64_to_cpu(findData.Gid); 143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
144 inode->i_uid = cifs_sb->mnt_uid;
145 else
146 inode->i_uid = le64_to_cpu(findData.Uid);
147
148 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
149 inode->i_gid = cifs_sb->mnt_gid;
150 else
151 inode->i_gid = le64_to_cpu(findData.Gid);
152
144 inode->i_nlink = le64_to_cpu(findData.Nlinks); 153 inode->i_nlink = le64_to_cpu(findData.Nlinks);
145 154
146 spin_lock(&inode->i_lock); 155 spin_lock(&inode->i_lock);
@@ -178,13 +187,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
178 &cifs_file_direct_nobrl_ops; 187 &cifs_file_direct_nobrl_ops;
179 else 188 else
180 inode->i_fop = &cifs_file_direct_ops; 189 inode->i_fop = &cifs_file_direct_ops;
181 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
182 inode->i_fop = &cifs_file_nobrl_ops; 191 inode->i_fop = &cifs_file_nobrl_ops;
183 else /* not direct, send byte range locks */ 192 else /* not direct, send byte range locks */
184 inode->i_fop = &cifs_file_ops; 193 inode->i_fop = &cifs_file_ops;
185 194
186 /* check if server can support readpages */ 195 /* check if server can support readpages */
187 if(pTcon->ses->server->maxBuf < 196 if (pTcon->ses->server->maxBuf <
188 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
189 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
190 else 199 else
@@ -220,7 +229,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
220 229
221 pbuf = buf; 230 pbuf = buf;
222 231
223 if(size == 0) { 232 if (size == 0) {
224 inode->i_mode |= S_IFIFO; 233 inode->i_mode |= S_IFIFO;
225 return 0; 234 return 0;
226 } else if (size < 8) { 235 } else if (size < 8) {
@@ -239,11 +248,11 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
239 netfid, 248 netfid,
240 24 /* length */, 0 /* offset */, 249 24 /* length */, 0 /* offset */,
241 &bytes_read, &pbuf, &buf_type); 250 &bytes_read, &pbuf, &buf_type);
242 if((rc == 0) && (bytes_read >= 8)) { 251 if ((rc == 0) && (bytes_read >= 8)) {
243 if(memcmp("IntxBLK", pbuf, 8) == 0) { 252 if (memcmp("IntxBLK", pbuf, 8) == 0) {
244 cFYI(1,("Block device")); 253 cFYI(1,("Block device"));
245 inode->i_mode |= S_IFBLK; 254 inode->i_mode |= S_IFBLK;
246 if(bytes_read == 24) { 255 if (bytes_read == 24) {
247 /* we have enough to decode dev num */ 256 /* we have enough to decode dev num */
248 __u64 mjr; /* major */ 257 __u64 mjr; /* major */
249 __u64 mnr; /* minor */ 258 __u64 mnr; /* minor */
@@ -251,10 +260,10 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
251 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 260 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
252 inode->i_rdev = MKDEV(mjr, mnr); 261 inode->i_rdev = MKDEV(mjr, mnr);
253 } 262 }
254 } else if(memcmp("IntxCHR", pbuf, 8) == 0) { 263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
255 cFYI(1,("Char device")); 264 cFYI(1,("Char device"));
256 inode->i_mode |= S_IFCHR; 265 inode->i_mode |= S_IFCHR;
257 if(bytes_read == 24) { 266 if (bytes_read == 24) {
258 /* we have enough to decode dev num */ 267 /* we have enough to decode dev num */
259 __u64 mjr; /* major */ 268 __u64 mjr; /* major */
260 __u64 mnr; /* minor */ 269 __u64 mnr; /* minor */
@@ -262,7 +271,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
262 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
263 inode->i_rdev = MKDEV(mjr, mnr); 272 inode->i_rdev = MKDEV(mjr, mnr);
264 } 273 }
265 } else if(memcmp("IntxLNK", pbuf, 7) == 0) { 274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
266 cFYI(1,("Symlink")); 275 cFYI(1,("Symlink"));
267 inode->i_mode |= S_IFLNK; 276 inode->i_mode |= S_IFLNK;
268 } else { 277 } else {
@@ -293,7 +302,7 @@ static int get_sfu_uid_mode(struct inode * inode,
293 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 302 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
294 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 303 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
295 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 304 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
296 if(rc < 0) 305 if (rc < 0)
297 return (int)rc; 306 return (int)rc;
298 else if (rc > 3) { 307 else if (rc > 3) {
299 mode = le32_to_cpu(*((__le32 *)ea_value)); 308 mode = le32_to_cpu(*((__le32 *)ea_value));
@@ -348,7 +357,7 @@ int cifs_get_inode_info(struct inode **pinode,
348 /* BB optimize code so we do not make the above call 357 /* BB optimize code so we do not make the above call
349 when server claims no NT SMB support and the above call 358 when server claims no NT SMB support and the above call
350 failed at least once - set flag in tcon or mount */ 359 failed at least once - set flag in tcon or mount */
351 if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 360 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
352 rc = SMBQueryInformation(xid, pTcon, search_path, 361 rc = SMBQueryInformation(xid, pTcon, search_path,
353 pfindData, cifs_sb->local_nls, 362 pfindData, cifs_sb->local_nls,
354 cifs_sb->mnt_cifs_flags & 363 cifs_sb->mnt_cifs_flags &
@@ -425,7 +434,7 @@ int cifs_get_inode_info(struct inode **pinode,
425 } else /* do we need cast or hash to ino? */ 434 } else /* do we need cast or hash to ino? */
426 (*pinode)->i_ino = inode_num; 435 (*pinode)->i_ino = inode_num;
427 } /* else ino incremented to unique num in new_inode*/ 436 } /* else ino incremented to unique num in new_inode*/
428 if(sb->s_flags & MS_NOATIME) 437 if (sb->s_flags & MS_NOATIME)
429 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 438 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
430 insert_inode_hash(*pinode); 439 insert_inode_hash(*pinode);
431 } 440 }
@@ -442,7 +451,7 @@ int cifs_get_inode_info(struct inode **pinode,
442 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 451 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
443 452
444 /* Linux can not store file creation time so ignore it */ 453 /* Linux can not store file creation time so ignore it */
445 if(pfindData->LastAccessTime) 454 if (pfindData->LastAccessTime)
446 inode->i_atime = cifs_NTtimeToUnix 455 inode->i_atime = cifs_NTtimeToUnix
447 (le64_to_cpu(pfindData->LastAccessTime)); 456 (le64_to_cpu(pfindData->LastAccessTime));
448 else /* do not need to use current_fs_time - time not stored */ 457 else /* do not need to use current_fs_time - time not stored */
@@ -452,7 +461,7 @@ int cifs_get_inode_info(struct inode **pinode,
452 inode->i_ctime = 461 inode->i_ctime =
453 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 462 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
454 cFYI(0, ("Attributes came in as 0x%x", attr)); 463 cFYI(0, ("Attributes came in as 0x%x", attr));
455 if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 464 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
456 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 465 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
457 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 466 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
458 } 467 }
@@ -521,8 +530,10 @@ int cifs_get_inode_info(struct inode **pinode,
521 530
522 /* BB fill in uid and gid here? with help from winbind? 531 /* BB fill in uid and gid here? with help from winbind?
523 or retrieve from NTFS stream extended attribute */ 532 or retrieve from NTFS stream extended attribute */
524 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 533 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
525 /* fill in uid, gid, mode from server ACL */ 534 /* fill in uid, gid, mode from server ACL */
535 /* BB FIXME this should also take into account the
536 * default uid specified on mount if present */
526 get_sfu_uid_mode(inode, search_path, cifs_sb, xid); 537 get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
527 } else if (atomic_read(&cifsInfo->inUse) == 0) { 538 } else if (atomic_read(&cifsInfo->inUse) == 0) {
528 inode->i_uid = cifs_sb->mnt_uid; 539 inode->i_uid = cifs_sb->mnt_uid;
@@ -541,12 +552,12 @@ int cifs_get_inode_info(struct inode **pinode,
541 &cifs_file_direct_nobrl_ops; 552 &cifs_file_direct_nobrl_ops;
542 else 553 else
543 inode->i_fop = &cifs_file_direct_ops; 554 inode->i_fop = &cifs_file_direct_ops;
544 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 555 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
545 inode->i_fop = &cifs_file_nobrl_ops; 556 inode->i_fop = &cifs_file_nobrl_ops;
546 else /* not direct, send byte range locks */ 557 else /* not direct, send byte range locks */
547 inode->i_fop = &cifs_file_ops; 558 inode->i_fop = &cifs_file_ops;
548 559
549 if(pTcon->ses->server->maxBuf < 560 if (pTcon->ses->server->maxBuf <
550 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 561 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
551 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 562 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
552 else 563 else
@@ -597,7 +608,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
597 608
598 xid = GetXid(); 609 xid = GetXid();
599 610
600 if(inode) 611 if (inode)
601 cifs_sb = CIFS_SB(inode->i_sb); 612 cifs_sb = CIFS_SB(inode->i_sb);
602 else 613 else
603 cifs_sb = CIFS_SB(direntry->d_sb); 614 cifs_sb = CIFS_SB(direntry->d_sb);
@@ -723,7 +734,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
723 when needed */ 734 when needed */
724 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 735 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
725 } 736 }
726 if(inode) { 737 if (inode) {
727 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 738 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
728 cifsInode = CIFS_I(inode); 739 cifsInode = CIFS_I(inode);
729 cifsInode->time = 0; /* force revalidate of dir as well */ 740 cifsInode->time = 0; /* force revalidate of dir as well */