diff options
author | Steve French <sfrench@us.ibm.com> | 2007-04-30 16:13:06 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-04-30 16:13:06 -0400 |
commit | 4523cc3044d1bc7fcf3d7fee75d62bc76b8e1abb (patch) | |
tree | 31c2b6c0a81f14ec812d09586eb8ef5a586743cb /fs/cifs/cifsfs.c | |
parent | 984acfe1cfb613257a15f30b3cf60ae7e4ed8f06 (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/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index dd03e680f8f8..5036dae09cd7 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -100,7 +100,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
100 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | 100 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; |
101 | sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); | 101 | sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); |
102 | cifs_sb = CIFS_SB(sb); | 102 | cifs_sb = CIFS_SB(sb); |
103 | if(cifs_sb == NULL) | 103 | if (cifs_sb == NULL) |
104 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | 105 | ||
106 | rc = cifs_mount(sb, cifs_sb, data, devname); | 106 | rc = cifs_mount(sb, cifs_sb, data, devname); |
@@ -115,10 +115,10 @@ cifs_read_super(struct super_block *sb, void *data, | |||
115 | sb->s_magic = CIFS_MAGIC_NUMBER; | 115 | sb->s_magic = CIFS_MAGIC_NUMBER; |
116 | sb->s_op = &cifs_super_ops; | 116 | sb->s_op = &cifs_super_ops; |
117 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 117 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
118 | if(experimEnabled != 0) | 118 | if (experimEnabled != 0) |
119 | sb->s_export_op = &cifs_export_ops; | 119 | sb->s_export_op = &cifs_export_ops; |
120 | #endif /* EXPERIMENTAL */ | 120 | #endif /* EXPERIMENTAL */ |
121 | /* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) | 121 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) |
122 | sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ | 122 | sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ |
123 | #ifdef CONFIG_CIFS_QUOTA | 123 | #ifdef CONFIG_CIFS_QUOTA |
124 | sb->s_qcop = &cifs_quotactl_ops; | 124 | sb->s_qcop = &cifs_quotactl_ops; |
@@ -147,8 +147,8 @@ out_no_root: | |||
147 | iput(inode); | 147 | iput(inode); |
148 | 148 | ||
149 | out_mount_failed: | 149 | out_mount_failed: |
150 | if(cifs_sb) { | 150 | if (cifs_sb) { |
151 | if(cifs_sb->local_nls) | 151 | if (cifs_sb->local_nls) |
152 | unload_nls(cifs_sb->local_nls); | 152 | unload_nls(cifs_sb->local_nls); |
153 | kfree(cifs_sb); | 153 | kfree(cifs_sb); |
154 | } | 154 | } |
@@ -163,7 +163,7 @@ cifs_put_super(struct super_block *sb) | |||
163 | 163 | ||
164 | cFYI(1, ("In cifs_put_super")); | 164 | cFYI(1, ("In cifs_put_super")); |
165 | cifs_sb = CIFS_SB(sb); | 165 | cifs_sb = CIFS_SB(sb); |
166 | if(cifs_sb == NULL) { | 166 | if (cifs_sb == NULL) { |
167 | cFYI(1,("Empty cifs superblock info passed to unmount")); | 167 | cFYI(1,("Empty cifs superblock info passed to unmount")); |
168 | return; | 168 | return; |
169 | } | 169 | } |
@@ -208,14 +208,14 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
208 | 208 | ||
209 | /* Only need to call the old QFSInfo if failed | 209 | /* Only need to call the old QFSInfo if failed |
210 | on newer one */ | 210 | on newer one */ |
211 | if(rc) | 211 | if (rc) |
212 | if(pTcon->ses->capabilities & CAP_NT_SMBS) | 212 | if (pTcon->ses->capabilities & CAP_NT_SMBS) |
213 | rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ | 213 | rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ |
214 | 214 | ||
215 | /* Some old Windows servers also do not support level 103, retry with | 215 | /* Some old Windows servers also do not support level 103, retry with |
216 | older level one if old server failed the previous call or we | 216 | older level one if old server failed the previous call or we |
217 | bypassed it because we detected that this was an older LANMAN sess */ | 217 | bypassed it because we detected that this was an older LANMAN sess */ |
218 | if(rc) | 218 | if (rc) |
219 | rc = SMBOldQFSInfo(xid, pTcon, buf); | 219 | rc = SMBOldQFSInfo(xid, pTcon, buf); |
220 | /* | 220 | /* |
221 | int f_type; | 221 | int f_type; |
@@ -301,11 +301,19 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
301 | if (cifs_sb->tcon->ses->userName) | 301 | if (cifs_sb->tcon->ses->userName) |
302 | seq_printf(s, ",username=%s", | 302 | seq_printf(s, ",username=%s", |
303 | cifs_sb->tcon->ses->userName); | 303 | cifs_sb->tcon->ses->userName); |
304 | if(cifs_sb->tcon->ses->domainName) | 304 | if (cifs_sb->tcon->ses->domainName) |
305 | seq_printf(s, ",domain=%s", | 305 | seq_printf(s, ",domain=%s", |
306 | cifs_sb->tcon->ses->domainName); | 306 | cifs_sb->tcon->ses->domainName); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | ||
310 | seq_printf(s, ",posixpaths"); | ||
311 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
312 | !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) | ||
313 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
314 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
315 | !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) | ||
316 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
309 | seq_printf(s, ",rsize=%d",cifs_sb->rsize); | 317 | seq_printf(s, ",rsize=%d",cifs_sb->rsize); |
310 | seq_printf(s, ",wsize=%d",cifs_sb->wsize); | 318 | seq_printf(s, ",wsize=%d",cifs_sb->wsize); |
311 | } | 319 | } |
@@ -321,14 +329,14 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid, | |||
321 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 329 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
322 | struct cifsTconInfo *pTcon; | 330 | struct cifsTconInfo *pTcon; |
323 | 331 | ||
324 | if(cifs_sb) | 332 | if (cifs_sb) |
325 | pTcon = cifs_sb->tcon; | 333 | pTcon = cifs_sb->tcon; |
326 | else | 334 | else |
327 | return -EIO; | 335 | return -EIO; |
328 | 336 | ||
329 | 337 | ||
330 | xid = GetXid(); | 338 | xid = GetXid(); |
331 | if(pTcon) { | 339 | if (pTcon) { |
332 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); | 340 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); |
333 | } else { | 341 | } else { |
334 | return -EIO; | 342 | return -EIO; |
@@ -346,13 +354,13 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid, | |||
346 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 354 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
347 | struct cifsTconInfo *pTcon; | 355 | struct cifsTconInfo *pTcon; |
348 | 356 | ||
349 | if(cifs_sb) | 357 | if (cifs_sb) |
350 | pTcon = cifs_sb->tcon; | 358 | pTcon = cifs_sb->tcon; |
351 | else | 359 | else |
352 | return -EIO; | 360 | return -EIO; |
353 | 361 | ||
354 | xid = GetXid(); | 362 | xid = GetXid(); |
355 | if(pTcon) { | 363 | if (pTcon) { |
356 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); | 364 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); |
357 | } else { | 365 | } else { |
358 | rc = -EIO; | 366 | rc = -EIO; |
@@ -369,13 +377,13 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation) | |||
369 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 377 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
370 | struct cifsTconInfo *pTcon; | 378 | struct cifsTconInfo *pTcon; |
371 | 379 | ||
372 | if(cifs_sb) | 380 | if (cifs_sb) |
373 | pTcon = cifs_sb->tcon; | 381 | pTcon = cifs_sb->tcon; |
374 | else | 382 | else |
375 | return -EIO; | 383 | return -EIO; |
376 | 384 | ||
377 | xid = GetXid(); | 385 | xid = GetXid(); |
378 | if(pTcon) { | 386 | if (pTcon) { |
379 | cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); | 387 | cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); |
380 | } else { | 388 | } else { |
381 | rc = -EIO; | 389 | rc = -EIO; |
@@ -392,13 +400,13 @@ int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats) | |||
392 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 400 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
393 | struct cifsTconInfo *pTcon; | 401 | struct cifsTconInfo *pTcon; |
394 | 402 | ||
395 | if(cifs_sb) { | 403 | if (cifs_sb) { |
396 | pTcon = cifs_sb->tcon; | 404 | pTcon = cifs_sb->tcon; |
397 | } else { | 405 | } else { |
398 | return -EIO; | 406 | return -EIO; |
399 | } | 407 | } |
400 | xid = GetXid(); | 408 | xid = GetXid(); |
401 | if(pTcon) { | 409 | if (pTcon) { |
402 | cFYI(1,("pqstats %p",qstats)); | 410 | cFYI(1,("pqstats %p",qstats)); |
403 | } else { | 411 | } else { |
404 | rc = -EIO; | 412 | rc = -EIO; |
@@ -424,11 +432,11 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) | |||
424 | if (!(flags & MNT_FORCE)) | 432 | if (!(flags & MNT_FORCE)) |
425 | return; | 433 | return; |
426 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); | 434 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); |
427 | if(cifs_sb == NULL) | 435 | if (cifs_sb == NULL) |
428 | return; | 436 | return; |
429 | 437 | ||
430 | tcon = cifs_sb->tcon; | 438 | tcon = cifs_sb->tcon; |
431 | if(tcon == NULL) | 439 | if (tcon == NULL) |
432 | return; | 440 | return; |
433 | down(&tcon->tconSem); | 441 | down(&tcon->tconSem); |
434 | if (atomic_read(&tcon->useCount) == 1) | 442 | if (atomic_read(&tcon->useCount) == 1) |
@@ -437,7 +445,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) | |||
437 | 445 | ||
438 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ | 446 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ |
439 | /* cancel_notify_requests(tcon); */ | 447 | /* cancel_notify_requests(tcon); */ |
440 | if(tcon->ses && tcon->ses->server) | 448 | if (tcon->ses && tcon->ses->server) |
441 | { | 449 | { |
442 | cFYI(1,("wake up tasks now - umount begin not complete")); | 450 | cFYI(1,("wake up tasks now - umount begin not complete")); |
443 | wake_up_all(&tcon->ses->server->request_q); | 451 | wake_up_all(&tcon->ses->server->request_q); |
@@ -723,7 +731,7 @@ cifs_destroy_inodecache(void) | |||
723 | static int | 731 | static int |
724 | cifs_init_request_bufs(void) | 732 | cifs_init_request_bufs(void) |
725 | { | 733 | { |
726 | if(CIFSMaxBufSize < 8192) { | 734 | if (CIFSMaxBufSize < 8192) { |
727 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum | 735 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum |
728 | Unicode path name has to fit in any SMB/CIFS path based frames */ | 736 | Unicode path name has to fit in any SMB/CIFS path based frames */ |
729 | CIFSMaxBufSize = 8192; | 737 | CIFSMaxBufSize = 8192; |
@@ -740,7 +748,7 @@ cifs_init_request_bufs(void) | |||
740 | if (cifs_req_cachep == NULL) | 748 | if (cifs_req_cachep == NULL) |
741 | return -ENOMEM; | 749 | return -ENOMEM; |
742 | 750 | ||
743 | if(cifs_min_rcv < 1) | 751 | if (cifs_min_rcv < 1) |
744 | cifs_min_rcv = 1; | 752 | cifs_min_rcv = 1; |
745 | else if (cifs_min_rcv > 64) { | 753 | else if (cifs_min_rcv > 64) { |
746 | cifs_min_rcv = 64; | 754 | cifs_min_rcv = 64; |
@@ -750,7 +758,7 @@ cifs_init_request_bufs(void) | |||
750 | cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, | 758 | cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, |
751 | cifs_req_cachep); | 759 | cifs_req_cachep); |
752 | 760 | ||
753 | if(cifs_req_poolp == NULL) { | 761 | if (cifs_req_poolp == NULL) { |
754 | kmem_cache_destroy(cifs_req_cachep); | 762 | kmem_cache_destroy(cifs_req_cachep); |
755 | return -ENOMEM; | 763 | return -ENOMEM; |
756 | } | 764 | } |
@@ -771,7 +779,7 @@ cifs_init_request_bufs(void) | |||
771 | return -ENOMEM; | 779 | return -ENOMEM; |
772 | } | 780 | } |
773 | 781 | ||
774 | if(cifs_min_small < 2) | 782 | if (cifs_min_small < 2) |
775 | cifs_min_small = 2; | 783 | cifs_min_small = 2; |
776 | else if (cifs_min_small > 256) { | 784 | else if (cifs_min_small > 256) { |
777 | cifs_min_small = 256; | 785 | cifs_min_small = 256; |
@@ -781,7 +789,7 @@ cifs_init_request_bufs(void) | |||
781 | cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, | 789 | cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, |
782 | cifs_sm_req_cachep); | 790 | cifs_sm_req_cachep); |
783 | 791 | ||
784 | if(cifs_sm_req_poolp == NULL) { | 792 | if (cifs_sm_req_poolp == NULL) { |
785 | mempool_destroy(cifs_req_poolp); | 793 | mempool_destroy(cifs_req_poolp); |
786 | kmem_cache_destroy(cifs_req_cachep); | 794 | kmem_cache_destroy(cifs_req_cachep); |
787 | kmem_cache_destroy(cifs_sm_req_cachep); | 795 | kmem_cache_destroy(cifs_sm_req_cachep); |
@@ -811,7 +819,7 @@ cifs_init_mids(void) | |||
811 | 819 | ||
812 | /* 3 is a reasonable minimum number of simultaneous operations */ | 820 | /* 3 is a reasonable minimum number of simultaneous operations */ |
813 | cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep); | 821 | cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep); |
814 | if(cifs_mid_poolp == NULL) { | 822 | if (cifs_mid_poolp == NULL) { |
815 | kmem_cache_destroy(cifs_mid_cachep); | 823 | kmem_cache_destroy(cifs_mid_cachep); |
816 | return -ENOMEM; | 824 | return -ENOMEM; |
817 | } | 825 | } |
@@ -849,14 +857,14 @@ static int cifs_oplock_thread(void * dummyarg) | |||
849 | continue; | 857 | continue; |
850 | 858 | ||
851 | spin_lock(&GlobalMid_Lock); | 859 | spin_lock(&GlobalMid_Lock); |
852 | if(list_empty(&GlobalOplock_Q)) { | 860 | if (list_empty(&GlobalOplock_Q)) { |
853 | spin_unlock(&GlobalMid_Lock); | 861 | spin_unlock(&GlobalMid_Lock); |
854 | set_current_state(TASK_INTERRUPTIBLE); | 862 | set_current_state(TASK_INTERRUPTIBLE); |
855 | schedule_timeout(39*HZ); | 863 | schedule_timeout(39*HZ); |
856 | } else { | 864 | } else { |
857 | oplock_item = list_entry(GlobalOplock_Q.next, | 865 | oplock_item = list_entry(GlobalOplock_Q.next, |
858 | struct oplock_q_entry, qhead); | 866 | struct oplock_q_entry, qhead); |
859 | if(oplock_item) { | 867 | if (oplock_item) { |
860 | cFYI(1,("found oplock item to write out")); | 868 | cFYI(1,("found oplock item to write out")); |
861 | pTcon = oplock_item->tcon; | 869 | pTcon = oplock_item->tcon; |
862 | inode = oplock_item->pinode; | 870 | inode = oplock_item->pinode; |
@@ -870,7 +878,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
870 | /* mutex_lock(&inode->i_mutex);*/ | 878 | /* mutex_lock(&inode->i_mutex);*/ |
871 | if (S_ISREG(inode->i_mode)) { | 879 | if (S_ISREG(inode->i_mode)) { |
872 | rc = filemap_fdatawrite(inode->i_mapping); | 880 | rc = filemap_fdatawrite(inode->i_mapping); |
873 | if(CIFS_I(inode)->clientCanCacheRead == 0) { | 881 | if (CIFS_I(inode)->clientCanCacheRead == 0) { |
874 | filemap_fdatawait(inode->i_mapping); | 882 | filemap_fdatawait(inode->i_mapping); |
875 | invalidate_remote_inode(inode); | 883 | invalidate_remote_inode(inode); |
876 | } | 884 | } |
@@ -887,7 +895,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
887 | not bother sending an oplock release if session | 895 | not bother sending an oplock release if session |
888 | to server still is disconnected since oplock | 896 | to server still is disconnected since oplock |
889 | already released by the server in that case */ | 897 | already released by the server in that case */ |
890 | if(pTcon->tidStatus != CifsNeedReconnect) { | 898 | if (pTcon->tidStatus != CifsNeedReconnect) { |
891 | rc = CIFSSMBLock(0, pTcon, netfid, | 899 | rc = CIFSSMBLock(0, pTcon, netfid, |
892 | 0 /* len */ , 0 /* offset */, 0, | 900 | 0 /* len */ , 0 /* offset */, 0, |
893 | 0, LOCKING_ANDX_OPLOCK_RELEASE, | 901 | 0, LOCKING_ANDX_OPLOCK_RELEASE, |
@@ -921,7 +929,7 @@ static int cifs_dnotify_thread(void * dummyarg) | |||
921 | list_for_each(tmp, &GlobalSMBSessionList) { | 929 | list_for_each(tmp, &GlobalSMBSessionList) { |
922 | ses = list_entry(tmp, struct cifsSesInfo, | 930 | ses = list_entry(tmp, struct cifsSesInfo, |
923 | cifsSessionList); | 931 | cifsSessionList); |
924 | if(ses && ses->server && | 932 | if (ses && ses->server && |
925 | atomic_read(&ses->server->inFlight)) | 933 | atomic_read(&ses->server->inFlight)) |
926 | wake_up_all(&ses->server->response_q); | 934 | wake_up_all(&ses->server->response_q); |
927 | } | 935 | } |
@@ -970,10 +978,10 @@ init_cifs(void) | |||
970 | rwlock_init(&GlobalSMBSeslock); | 978 | rwlock_init(&GlobalSMBSeslock); |
971 | spin_lock_init(&GlobalMid_Lock); | 979 | spin_lock_init(&GlobalMid_Lock); |
972 | 980 | ||
973 | if(cifs_max_pending < 2) { | 981 | if (cifs_max_pending < 2) { |
974 | cifs_max_pending = 2; | 982 | cifs_max_pending = 2; |
975 | cFYI(1,("cifs_max_pending set to min of 2")); | 983 | cFYI(1,("cifs_max_pending set to min of 2")); |
976 | } else if(cifs_max_pending > 256) { | 984 | } else if (cifs_max_pending > 256) { |
977 | cifs_max_pending = 256; | 985 | cifs_max_pending = 256; |
978 | cFYI(1,("cifs_max_pending set to max of 256")); | 986 | cFYI(1,("cifs_max_pending set to max of 256")); |
979 | } | 987 | } |