* cifs and win2k8
@ 2011-10-21 11:18 Terrence Shipclark
[not found] ` <4EA154FC.3090601-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 10+ messages in thread
From: Terrence Shipclark @ 2011-10-21 11:18 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]
Hello,
This is my first time posting to this list, and I hope I am not breaking
any rules.
I have been attempting to get the cifs kernel modules to mount the
win2k8 dfs at my workplace. I did finally manage to get
the dfs to mount after modifying the kernel module with this small patch
@@ -3109,6 +3112,7 @@
cifs_sb, false);
if (!refrc) {
referral_walks_count++;
+ rc=0;
goto try_mount_again;
}
}
Although I dont 100% understand what I did, as I had a hard time
following the goto statements, I have a feeling that on initial setup it
would follow the DFS referral, however ultimately fail as it exited
because rc was still set to -6.
So now For my second problem.
Within the dfs tree there is a referral to //server/share$/folder. My
user has access to //server/share$/folder, however do not have access to
//server/$share. While following the referral the cifs module does a
QUERY_PATH_INFO on \\server\share$\folder, and then is followed up by a
QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
STATUS_ACCESS_DENIED from the server.
Traversing the same path with smbclient \\server\share$ is never
queried.Perhaps I am doing something wrong?
I have been attempting to connect to this dfs from linux for about 2
years,and this is the closest I have gotten, so any help would be
appreciated.
terry
[-- Attachment #2: dmesg-output.txt --]
[-- Type: text/plain, Size: 32950 bytes --]
[ 2642.002554] fs/cifs/inode.c: CIFS VFS: in cifs_revalidate_dentry_attr as Xid: 1253 with uid: 1000
[ 2642.002558] fs/cifs/inode.c: Update attributes: \\FIRE\Shares inode 0xffff8800b0178048 count 2 dentry: 0xffff8800b627b300 d_time 0 jiffies 4295552796
[ 2642.002560] fs/cifs/inode.c: Getting info on \\FIRE\Shares
[ 2642.002566] fs/cifs/transport.c: For smb_command 50
[ 2642.002568] fs/cifs/transport.c: Sending smb: total_len 104
[ 2642.003593] fs/cifs/connect.c: rfc1002 length 0xa8
[ 2642.003604] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1042 state=4
[ 2642.003610] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 5066549580883428
[ 2642.003612] fs/cifs/inode.c: cifs_revalidate_cache: inode 5066549580883428 is unchanged
[ 2642.003615] fs/cifs/inode.c: inode 0xffff8800b0178048 old_time=4295528240 new_time=4295552796
[ 2642.003619] fs/cifs/inode.c: CIFS VFS: leaving cifs_revalidate_dentry_attr (xid = 1253) rc = 0
[ 2642.003626] fs/cifs/inode.c: CIFS VFS: in cifs_revalidate_dentry_attr as Xid: 1254 with uid: 1000
[ 2642.003630] fs/cifs/inode.c: Update attributes: \\FIRE\Shares\Departmental inode 0xffff8800b0179008 count 1 dentry: 0xffff8800366e7300 d_time 4294936195 jiffies 4295552796
[ 2642.003633] fs/cifs/inode.c: Getting info on \\FIRE\Shares\Departmental
[ 2642.003636] fs/cifs/transport.c: For smb_command 50
[ 2642.003638] fs/cifs/transport.c: Sending smb: total_len 130
[ 2642.004542] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.004546] fs/cifs/connect.c: invalid transact2 word count
[ 2642.004554] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1043 state=4
[ 2642.004560] Status code returned 0xc0000257 NT_STATUS_PATH_NOT_COVERED
[ 2642.004563] fs/cifs/netmisc.c: Mapping smb error code 0xc0000257 to POSIX err -66
[ 2642.004566] fs/cifs/cifssmb.c: Send error in QPathInfo = -66
[ 2642.004568] fs/cifs/inode.c: creating fake fattr for DFS referral
[ 2642.004571] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 21
[ 2642.004573] fs/cifs/inode.c: cifs_revalidate_cache: invalidating inode 21 mapping
[ 2642.004576] fs/cifs/inode.c: inode 0xffff8800b0179008 old_time=4295528241 new_time=4295552797
[ 2642.004579] fs/cifs/inode.c: CIFS VFS: leaving cifs_revalidate_dentry_attr (xid = 1254) rc = 0
[ 2642.004584] fs/cifs/inode.c: CIFS VFS: in cifs_revalidate_dentry_attr as Xid: 1255 with uid: 1000
[ 2642.004588] fs/cifs/inode.c: Update attributes: \\FIRE\Departments$ inode 0xffff8800b0179548 count 1 dentry: 0xffff8800366e7a80 d_time -131940482123136 jiffies 4295552797
[ 2642.004591] fs/cifs/inode.c: Getting info on \\FIRE\Departments$
[ 2642.004594] fs/cifs/transport.c: For smb_command 50
[ 2642.004596] fs/cifs/transport.c: Sending smb: total_len 116
[ 2642.005480] fs/cifs/connect.c: rfc1002 length 0xb4
[ 2642.005488] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1044 state=4
[ 2642.005492] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 562949953513329
[ 2642.005495] fs/cifs/inode.c: cifs_revalidate_cache: inode 562949953513329 is unchanged
[ 2642.005497] fs/cifs/inode.c: inode 0xffff8800b0179548 old_time=4295551216 new_time=4295552797
[ 2642.005500] fs/cifs/inode.c: CIFS VFS: leaving cifs_revalidate_dentry_attr (xid = 1255) rc = 0
[ 2642.005507] fs/cifs/inode.c: CIFS VFS: in cifs_revalidate_dentry_attr as Xid: 1256 with uid: 1000
[ 2642.005511] fs/cifs/inode.c: Update attributes: \\FIRE\Departments$\folder inode 0xffff8800b01b9a88 count 1 dentry: 0xffff88009979a0c0 d_time 4295528259 jiffies 4295552797
[ 2642.005514] fs/cifs/inode.c: Getting info on \\FIRE\Departments$\folder
[ 2642.005517] fs/cifs/transport.c: For smb_command 50
[ 2642.005519] fs/cifs/transport.c: Sending smb: total_len 124
[ 2642.006297] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.006300] fs/cifs/connect.c: invalid transact2 word count
[ 2642.006307] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1045 state=4
[ 2642.006311] Status code returned 0xc0000257 NT_STATUS_PATH_NOT_COVERED
[ 2642.006313] fs/cifs/netmisc.c: Mapping smb error code 0xc0000257 to POSIX err -66
[ 2642.006316] fs/cifs/cifssmb.c: Send error in QPathInfo = -66
[ 2642.006318] fs/cifs/inode.c: creating fake fattr for DFS referral
[ 2642.006320] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 1656
[ 2642.006322] fs/cifs/inode.c: cifs_revalidate_cache: invalidating inode 1656 mapping
[ 2642.006325] fs/cifs/inode.c: inode 0xffff8800b01b9a88 old_time=4295528259 new_time=4295552797
[ 2642.006328] fs/cifs/inode.c: CIFS VFS: leaving cifs_revalidate_dentry_attr (xid = 1256) rc = 0
[ 2642.006336] fs/cifs/dir.c: CIFS VFS: in cifs_lookup as Xid: 1257 with uid: 1000
[ 2642.006339] fs/cifs/dir.c: parent inode = 0xffff8800b0179548 name is: folder and dentry = 0xffff880080c13c00
[ 2642.006342] fs/cifs/dir.c: NULL inode in lookup
[ 2642.006344] fs/cifs/dir.c: Full path: \\FIRE\Departments$\folder inode = 0x (null)
[ 2642.006346] fs/cifs/inode.c: Getting info on \\FIRE\Departments$\folder
[ 2642.006349] fs/cifs/transport.c: For smb_command 50
[ 2642.006351] fs/cifs/transport.c: Sending smb: total_len 124
[ 2642.007216] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.007219] fs/cifs/connect.c: invalid transact2 word count
[ 2642.007225] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1046 state=4
[ 2642.007229] Status code returned 0xc0000257 NT_STATUS_PATH_NOT_COVERED
[ 2642.007232] fs/cifs/netmisc.c: Mapping smb error code 0xc0000257 to POSIX err -66
[ 2642.007235] fs/cifs/cifssmb.c: Send error in QPathInfo = -66
[ 2642.007237] fs/cifs/inode.c: creating fake fattr for DFS referral
[ 2642.007240] fs/cifs/inode.c: looking for uniqueid=1657
[ 2642.007243] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 1657
[ 2642.007245] fs/cifs/inode.c: cifs_revalidate_cache: inode 1657 is new
[ 2642.007248] fs/cifs/inode.c: inode 0xffff8800b01b9d28 old_time=0 new_time=4295552797
[ 2642.007252] fs/cifs/dir.c: CIFS VFS: leaving cifs_lookup (xid = 1257) rc = 0
[ 2642.007255] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_d_automount
[ 2642.007256] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_do_automount
[ 2642.007259] fs/cifs/cifs_dfs_ref.c: CIFS VFS: in cifs_dfs_do_automount as Xid: 1258 with uid: 1000
[ 2642.007262] fs/cifs/cifssmb.c: In GetDFSRefer the path \FIRE\Departments$\folder
[ 2642.007265] fs/cifs/transport.c: For smb_command 50
[ 2642.007267] fs/cifs/transport.c: Sending smb: total_len 120
[ 2642.007994] fs/cifs/connect.c: rfc1002 length 0xe2
[ 2642.008132] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1047 state=4
[ 2642.008134] fs/cifs/cifssmb.c: Decoding GetDFSRefer response BCC: 167 Offset 56
[ 2642.008135] fs/cifs/cifssmb.c: num_referrals: 1 dfs flags: 0x2 ...
[ 2642.008136]
[ 2642.008140] fs/cifs/cifs_dfs_ref.c: CIFS VFS: leaving cifs_dfs_do_automount (xid = 1258) rc = 0
[ 2642.008141] fs/cifs/cifs_dfs_ref.c: DFS: ref path: \FIRE\Departments$\folder
[ 2642.008142] fs/cifs/cifs_dfs_ref.c: DFS: node path: \server\share$\folder
[ 2642.008144] fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0
[ 2642.008145] fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 22
[ 2642.008153] fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: resolved: server to 10.10.10.157
[ 2642.008164] fs/cifs/cifsfs.c: Devname: \\server\share$ flags: 0
[ 2642.008169] fs/cifs/connect.c: Domain name set
[ 2642.008171] fs/cifs/connect.c: prefix path /folder
[ 2642.008172] fs/cifs/connect.c: Username: shipclar
[ 2642.008175] fs/cifs/connect.c: file mode: 0x1ed dir mode: 0x1ed
[ 2642.008229] fs/cifs/connect.c: CIFS VFS: in cifs_mount as Xid: 1259 with uid: 1000
[ 2642.008231] fs/cifs/connect.c: UNC: \\server\share$ ip: 10.10.10.157
[ 2642.008242] fs/cifs/connect.c: Socket created
[ 2642.008243] fs/cifs/connect.c: sndbuf 16384 rcvbuf 87380 rcvtimeo 0x6d6
[ 2642.008879] fs/cifs/connect.c: CIFS VFS: in cifs_get_smb_ses as Xid: 1260 with uid: 1000
[ 2642.008881] fs/cifs/connect.c: Demultiplex PID: 4387
[ 2642.008882] fs/cifs/connect.c: Existing smb sess not found
[ 2642.008885] fs/cifs/cifssmb.c: secFlags 0x7
[ 2642.008887] fs/cifs/transport.c: For smb_command 114
[ 2642.008888] fs/cifs/transport.c: Sending smb: total_len 82
[ 2642.015194] fs/cifs/connect.c: rfc1002 length 0x67
[ 2642.015205] fs/cifs/transport.c: cifs_sync_mid_result: cmd=114 mid=1 state=4
[ 2642.015209] fs/cifs/cifssmb.c: Dialect: 2
[ 2642.015212] fs/cifs/cifssmb.c: negprot rc 0
[ 2642.015214] fs/cifs/connect.c: Security Mode: 0x3 Capabilities: 0x1e3fd TimeAdjust: 14400
[ 2642.015216] fs/cifs/sess.c: sess setup type 1
[ 2642.015241] fs/cifs/transport.c: For smb_command 115
[ 2642.015243] fs/cifs/transport.c: Sending smb: total_len 260
[ 2642.017881] fs/cifs/connect.c: rfc1002 length 0xef
[ 2642.017893] fs/cifs/transport.c: cifs_sync_mid_result: cmd=115 mid=2 state=4
[ 2642.017896] fs/cifs/misc.c: Null buffer passed to cifs_small_buf_release
[ 2642.017899] fs/cifs/sess.c: UID = 57346
[ 2642.017901] fs/cifs/sess.c: bleft 193
[ 2642.017904] fs/cifs/sess.c: serverOS=Windows Server (R) 2008 Standard 6001 Service Pack 1
[ 2642.017908] fs/cifs/sess.c: serverNOS=Windows Server (R) 2008 Standard 6.0
[ 2642.017911] fs/cifs/sess.c: serverDomain=TURTLE
[ 2642.017913] fs/cifs/sess.c: ssetup freeing small buf ffff880129c83480
[ 2642.017915] fs/cifs/connect.c: CIFS Session Established successfully
[ 2642.017917] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_smb_ses (xid = 1260) rc = 0
[ 2642.017921] fs/cifs/connect.c: CIFS VFS: in cifs_get_tcon as Xid: 1261 with uid: 1000
[ 2642.017924] fs/cifs/transport.c: For smb_command 117
[ 2642.017926] fs/cifs/transport.c: Sending smb: total_len 80
[ 2642.018359] fs/cifs/connect.c: rfc1002 length 0x42
[ 2642.018368] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=3 state=4
[ 2642.018371] fs/cifs/connect.c: disk share connection
[ 2642.018373] fs/cifs/connect.c: nativeFileSystem=NTFS
[ 2642.018375] fs/cifs/connect.c: Tcon flags: 0x1
[ 2642.018377] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_tcon (xid = 1261) rc = 0
[ 2642.018379] fs/cifs/connect.c: CIFS Tcon rc = 0
[ 2642.018381] fs/cifs/cifssmb.c: In QFSDeviceInfo
[ 2642.018384] fs/cifs/transport.c: For smb_command 50
[ 2642.018386] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.018605] fs/cifs/connect.c: rfc1002 length 0x44
[ 2642.018613] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=4 state=4
[ 2642.018616] fs/cifs/cifssmb.c: In QFSAttributeInfo
[ 2642.018619] fs/cifs/transport.c: For smb_command 50
[ 2642.018621] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.018842] fs/cifs/connect.c: rfc1002 length 0x50
[ 2642.018849] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=5 state=4
[ 2642.018853] fs/cifs/connect.c: build_unc_path_to_root: full_path=\\server\share$\folder
[ 2642.018856] fs/cifs/transport.c: For smb_command 117
[ 2642.018858] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.019058] fs/cifs/connect.c: rfc1002 length 0x3c
[ 2642.019065] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=6 state=4
[ 2642.019068] fs/cifs/connect.c: CIFS Tcon rc = 0 ipc_tid = 43014
[ 2642.019070] fs/cifs/cifssmb.c: In GetDFSRefer the path \server\share$
[ 2642.019073] fs/cifs/transport.c: For smb_command 50
[ 2642.019075] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.019229] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.019232] fs/cifs/connect.c: invalid transact2 word count
[ 2642.019239] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=7 state=4
[ 2642.019243] Status code returned 0xc000019c NT_STATUS_FS_DRIVER_REQUIRED
[ 2642.019247] fs/cifs/netmisc.c: Mapping smb error code 0xc000019c to POSIX err -5
[ 2642.019250] fs/cifs/cifssmb.c: Send error in GetDFSRefer = -5
[ 2642.019253] fs/cifs/transport.c: For smb_command 50
[ 2642.019255] fs/cifs/transport.c: Sending smb: total_len 86
[ 2642.019529] fs/cifs/connect.c: rfc1002 length 0x9c
[ 2642.019537] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=8 state=4
[ 2642.019541] fs/cifs/connect.c: SPOT#2
[ 2642.019543] fs/cifs/connect.c: CIFS VFS: leaving cifs_mount (xid = 1259) rc = 0
[ 2642.019559] fs/cifs/inode.c: CIFS VFS: in cifs_root_iget as Xid: 1262 with uid: 1000
[ 2642.019561] fs/cifs/inode.c: Getting info on
[ 2642.019563] fs/cifs/transport.c: For smb_command 50
[ 2642.019565] fs/cifs/transport.c: Sending smb: total_len 78
[ 2642.019859] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.019862] fs/cifs/connect.c: invalid transact2 word count
[ 2642.019869] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=9 state=4
[ 2642.019871] Status code returned 0xc0000022 NT_STATUS_ACCESS_DENIED
[ 2642.019875] fs/cifs/netmisc.c: Mapping smb error code 0xc0000022 to POSIX err -13
[ 2642.019878] fs/cifs/cifssmb.c: Send error in QPathInfo = -13
[ 2642.019880] CIFS VFS: cifs_read_super: get root inode failed
[ 2642.019886] fs/cifs/connect.c: cifs_put_tcon: tc_count=1
[ 2642.019887]
[ 2642.019889] fs/cifs/connect.c: CIFS VFS: in cifs_put_tcon as Xid: 1263 with uid: 1000
[ 2642.019891] fs/cifs/cifssmb.c: In tree disconnect
[ 2642.019894] fs/cifs/transport.c: For smb_command 113
[ 2642.019896] fs/cifs/transport.c: Sending smb: total_len 39
[ 2642.020059] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.020063] fs/cifs/transport.c: cifs_sync_mid_result: cmd=113 mid=10 state=4
[ 2642.020066] fs/cifs/connect.c: cifs_put_smb_ses: ses_count=1
[ 2642.020067]
[ 2642.020068] fs/cifs/connect.c: CIFS VFS: in cifs_put_smb_ses as Xid: 1264 with uid: 1000
[ 2642.020070] fs/cifs/cifssmb.c: In SMBLogoff for session disconnect
[ 2642.020072] fs/cifs/transport.c: For smb_command 116
[ 2642.020073] fs/cifs/transport.c: Sending smb: total_len 43
[ 2642.020508] fs/cifs/connect.c: rfc1002 length 0x2b
[ 2642.020630] fs/cifs/transport.c: cifs_sync_mid_result: cmd=116 mid=11 state=4
[ 2642.040025] fs/cifs/cifs_dfs_ref.c: cifs_dfs_do_automount: cifs_dfs_do_refmount:\server\share$\folder , mnt:fffffffffffffff3
[ 2642.040029] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_do_automount
[ 2642.040031] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_d_automount [automount failed]
[ 2642.040048] fs/cifs/dir.c: CIFS VFS: in cifs_lookup as Xid: 1265 with uid: 1000
[ 2642.040051] fs/cifs/dir.c: parent inode = 0xffff8800b0179548 name is: folder and dentry = 0xffff880080c13a80
[ 2642.040054] fs/cifs/dir.c: NULL inode in lookup
[ 2642.040057] fs/cifs/dir.c: Full path: \\FIRE\Departments$\folder inode = 0x (null)
[ 2642.040059] fs/cifs/inode.c: Getting info on \\FIRE\Departments$\folder
[ 2642.040063] fs/cifs/transport.c: For smb_command 50
[ 2642.040065] fs/cifs/transport.c: Sending smb: total_len 124
[ 2642.040920] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.040924] fs/cifs/connect.c: invalid transact2 word count
[ 2642.040931] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1048 state=4
[ 2642.040936] Status code returned 0xc0000257 NT_STATUS_PATH_NOT_COVERED
[ 2642.040939] fs/cifs/netmisc.c: Mapping smb error code 0xc0000257 to POSIX err -66
[ 2642.040942] fs/cifs/cifssmb.c: Send error in QPathInfo = -66
[ 2642.040944] fs/cifs/inode.c: creating fake fattr for DFS referral
[ 2642.040947] fs/cifs/inode.c: looking for uniqueid=1658
[ 2642.040950] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 1658
[ 2642.040952] fs/cifs/inode.c: cifs_revalidate_cache: inode 1658 is new
[ 2642.040955] fs/cifs/inode.c: inode 0xffff8800b01b9a88 old_time=0 new_time=4295552806
[ 2642.040958] fs/cifs/dir.c: CIFS VFS: leaving cifs_lookup (xid = 1265) rc = 0
[ 2642.040961] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_d_automount
[ 2642.040963] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_do_automount
[ 2642.040966] fs/cifs/cifs_dfs_ref.c: CIFS VFS: in cifs_dfs_do_automount as Xid: 1266 with uid: 1000
[ 2642.040968] fs/cifs/cifssmb.c: In GetDFSRefer the path \FIRE\Departments$\folder
[ 2642.040971] fs/cifs/transport.c: For smb_command 50
[ 2642.040973] fs/cifs/transport.c: Sending smb: total_len 120
[ 2642.041656] fs/cifs/connect.c: rfc1002 length 0xe2
[ 2642.041665] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1049 state=4
[ 2642.041668] fs/cifs/cifssmb.c: Decoding GetDFSRefer response BCC: 167 Offset 56
[ 2642.041670] fs/cifs/cifssmb.c: num_referrals: 1 dfs flags: 0x2 ...
[ 2642.041671]
[ 2642.041676] fs/cifs/cifs_dfs_ref.c: CIFS VFS: leaving cifs_dfs_do_automount (xid = 1266) rc = 0
[ 2642.041679] fs/cifs/cifs_dfs_ref.c: DFS: ref path: \FIRE\Departments$\folder
[ 2642.041680] fs/cifs/cifs_dfs_ref.c: DFS: node path: \server\share$\folder
[ 2642.041683] fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0
[ 2642.041684] fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 22
[ 2642.041692] fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: resolved: server to 10.10.10.157
[ 2642.041703] fs/cifs/cifsfs.c: Devname: \\server\share$ flags: 0
[ 2642.041709] fs/cifs/connect.c: Domain name set
[ 2642.041712] fs/cifs/connect.c: prefix path /folder
[ 2642.041714] fs/cifs/connect.c: Username: shipclar
[ 2642.041717] fs/cifs/connect.c: file mode: 0x1ed dir mode: 0x1ed
[ 2642.041760] fs/cifs/connect.c: CIFS VFS: in cifs_mount as Xid: 1267 with uid: 1000
[ 2642.041763] fs/cifs/connect.c: UNC: \\server\share$ ip: 10.10.10.157
[ 2642.041774] fs/cifs/connect.c: Socket created
[ 2642.041776] fs/cifs/connect.c: sndbuf 16384 rcvbuf 87380 rcvtimeo 0x6d6
[ 2642.042090] fs/cifs/connect.c: CIFS VFS: in cifs_get_smb_ses as Xid: 1268 with uid: 1000
[ 2642.042092] fs/cifs/connect.c: Demultiplex PID: 4388
[ 2642.042094] fs/cifs/connect.c: Existing smb sess not found
[ 2642.042098] fs/cifs/cifssmb.c: secFlags 0x7
[ 2642.042100] fs/cifs/transport.c: For smb_command 114
[ 2642.042101] fs/cifs/transport.c: Sending smb: total_len 82
[ 2642.042309] fs/cifs/connect.c: rfc1002 length 0x67
[ 2642.042317] fs/cifs/transport.c: cifs_sync_mid_result: cmd=114 mid=1 state=4
[ 2642.042321] fs/cifs/cifssmb.c: Dialect: 2
[ 2642.042323] fs/cifs/cifssmb.c: negprot rc 0
[ 2642.042325] fs/cifs/connect.c: Security Mode: 0x3 Capabilities: 0x1e3fd TimeAdjust: 14400
[ 2642.042327] fs/cifs/sess.c: sess setup type 1
[ 2642.042348] fs/cifs/transport.c: For smb_command 115
[ 2642.042354] fs/cifs/transport.c: Sending smb: total_len 260
[ 2642.044669] fs/cifs/connect.c: rfc1002 length 0xef
[ 2642.044682] fs/cifs/transport.c: cifs_sync_mid_result: cmd=115 mid=2 state=4
[ 2642.044683] fs/cifs/misc.c: Null buffer passed to cifs_small_buf_release
[ 2642.044685] fs/cifs/sess.c: UID = 36866
[ 2642.044686] fs/cifs/sess.c: bleft 193
[ 2642.044688] fs/cifs/sess.c: serverOS=Windows Server (R) 2008 Standard 6001 Service Pack 1
[ 2642.044691] fs/cifs/sess.c: serverNOS=Windows Server (R) 2008 Standard 6.0
[ 2642.044692] fs/cifs/sess.c: serverDomain=TURTLE
[ 2642.044694] fs/cifs/sess.c: ssetup freeing small buf ffff880129c80e00
[ 2642.044695] fs/cifs/connect.c: CIFS Session Established successfully
[ 2642.044696] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_smb_ses (xid = 1268) rc = 0
[ 2642.044698] fs/cifs/connect.c: CIFS VFS: in cifs_get_tcon as Xid: 1269 with uid: 1000
[ 2642.044702] fs/cifs/transport.c: For smb_command 117
[ 2642.044703] fs/cifs/transport.c: Sending smb: total_len 80
[ 2642.045074] fs/cifs/connect.c: rfc1002 length 0x42
[ 2642.045080] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=3 state=4
[ 2642.045082] fs/cifs/connect.c: disk share connection
[ 2642.045084] fs/cifs/connect.c: nativeFileSystem=NTFS
[ 2642.045085] fs/cifs/connect.c: Tcon flags: 0x1
[ 2642.045086] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_tcon (xid = 1269) rc = 0
[ 2642.045087] fs/cifs/connect.c: CIFS Tcon rc = 0
[ 2642.045088] fs/cifs/cifssmb.c: In QFSDeviceInfo
[ 2642.045090] fs/cifs/transport.c: For smb_command 50
[ 2642.045091] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.045242] fs/cifs/connect.c: rfc1002 length 0x44
[ 2642.045250] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=4 state=4
[ 2642.045254] fs/cifs/cifssmb.c: In QFSAttributeInfo
[ 2642.045256] fs/cifs/transport.c: For smb_command 50
[ 2642.045258] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.045426] fs/cifs/connect.c: rfc1002 length 0x50
[ 2642.045434] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=5 state=4
[ 2642.045438] fs/cifs/connect.c: build_unc_path_to_root: full_path=\\server\share$\folder
[ 2642.045441] fs/cifs/transport.c: For smb_command 117
[ 2642.045443] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.045608] fs/cifs/connect.c: rfc1002 length 0x3c
[ 2642.045616] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=6 state=4
[ 2642.045619] fs/cifs/connect.c: CIFS Tcon rc = 0 ipc_tid = 6148
[ 2642.045621] fs/cifs/cifssmb.c: In GetDFSRefer the path \server\share$
[ 2642.045624] fs/cifs/transport.c: For smb_command 50
[ 2642.045625] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.045776] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.045779] fs/cifs/connect.c: invalid transact2 word count
[ 2642.045786] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=7 state=4
[ 2642.045790] Status code returned 0xc000019c NT_STATUS_FS_DRIVER_REQUIRED
[ 2642.045793] fs/cifs/netmisc.c: Mapping smb error code 0xc000019c to POSIX err -5
[ 2642.045796] fs/cifs/cifssmb.c: Send error in GetDFSRefer = -5
[ 2642.045799] fs/cifs/transport.c: For smb_command 50
[ 2642.045801] fs/cifs/transport.c: Sending smb: total_len 86
[ 2642.046044] fs/cifs/connect.c: rfc1002 length 0x9c
[ 2642.046051] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=8 state=4
[ 2642.046055] fs/cifs/connect.c: SPOT#2
[ 2642.046057] fs/cifs/connect.c: CIFS VFS: leaving cifs_mount (xid = 1267) rc = 0
[ 2642.046069] fs/cifs/inode.c: CIFS VFS: in cifs_root_iget as Xid: 1270 with uid: 1000
[ 2642.046071] fs/cifs/inode.c: Getting info on
[ 2642.046073] fs/cifs/transport.c: For smb_command 50
[ 2642.046075] fs/cifs/transport.c: Sending smb: total_len 78
[ 2642.046271] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.046274] fs/cifs/connect.c: invalid transact2 word count
[ 2642.046280] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=9 state=4
[ 2642.046283] Status code returned 0xc0000022 NT_STATUS_ACCESS_DENIED
[ 2642.046287] fs/cifs/netmisc.c: Mapping smb error code 0xc0000022 to POSIX err -13
[ 2642.046289] fs/cifs/cifssmb.c: Send error in QPathInfo = -13
[ 2642.046291] CIFS VFS: cifs_read_super: get root inode failed
[ 2642.046297] fs/cifs/connect.c: cifs_put_tcon: tc_count=1
[ 2642.046298]
[ 2642.046300] fs/cifs/connect.c: CIFS VFS: in cifs_put_tcon as Xid: 1271 with uid: 1000
[ 2642.046302] fs/cifs/cifssmb.c: In tree disconnect
[ 2642.046305] fs/cifs/transport.c: For smb_command 113
[ 2642.046307] fs/cifs/transport.c: Sending smb: total_len 39
[ 2642.046465] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.046470] fs/cifs/transport.c: cifs_sync_mid_result: cmd=113 mid=10 state=4
[ 2642.046472] fs/cifs/connect.c: cifs_put_smb_ses: ses_count=1
[ 2642.046472]
[ 2642.046474] fs/cifs/connect.c: CIFS VFS: in cifs_put_smb_ses as Xid: 1272 with uid: 1000
[ 2642.046475] fs/cifs/cifssmb.c: In SMBLogoff for session disconnect
[ 2642.046476] fs/cifs/transport.c: For smb_command 116
[ 2642.046478] fs/cifs/transport.c: Sending smb: total_len 43
[ 2642.046817] fs/cifs/connect.c: rfc1002 length 0x2b
[ 2642.046824] fs/cifs/transport.c: cifs_sync_mid_result: cmd=116 mid=11 state=4
[ 2642.084017] fs/cifs/cifs_dfs_ref.c: cifs_dfs_do_automount: cifs_dfs_do_refmount:\server\share$\folder , mnt:fffffffffffffff3
[ 2642.084021] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_do_automount
[ 2642.084023] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_d_automount [automount failed]
[ 2642.084033] fs/cifs/dir.c: CIFS VFS: in cifs_lookup as Xid: 1273 with uid: 1000
[ 2642.084035] fs/cifs/dir.c: parent inode = 0xffff8800b0179548 name is: folder and dentry = 0xffff880080c13300
[ 2642.084038] fs/cifs/dir.c: NULL inode in lookup
[ 2642.084040] fs/cifs/dir.c: Full path: \\FIRE\Departments$\folder inode = 0x (null)
[ 2642.084043] fs/cifs/inode.c: Getting info on \\FIRE\Departments$\folder
[ 2642.084047] fs/cifs/transport.c: For smb_command 50
[ 2642.084049] fs/cifs/transport.c: Sending smb: total_len 124
[ 2642.084908] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.084912] fs/cifs/connect.c: invalid transact2 word count
[ 2642.084919] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1050 state=4
[ 2642.084924] Status code returned 0xc0000257 NT_STATUS_PATH_NOT_COVERED
[ 2642.084927] fs/cifs/netmisc.c: Mapping smb error code 0xc0000257 to POSIX err -66
[ 2642.084930] fs/cifs/cifssmb.c: Send error in QPathInfo = -66
[ 2642.084932] fs/cifs/inode.c: creating fake fattr for DFS referral
[ 2642.084935] fs/cifs/inode.c: looking for uniqueid=1659
[ 2642.084937] fs/cifs/inode.c: cifs_revalidate_cache: revalidating inode 1659
[ 2642.084940] fs/cifs/inode.c: cifs_revalidate_cache: inode 1659 is new
[ 2642.084942] fs/cifs/inode.c: inode 0xffff8800b01b9d28 old_time=0 new_time=4295552817
[ 2642.084946] fs/cifs/dir.c: CIFS VFS: leaving cifs_lookup (xid = 1273) rc = 0
[ 2642.084949] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_d_automount
[ 2642.084950] fs/cifs/cifs_dfs_ref.c: in cifs_dfs_do_automount
[ 2642.084953] fs/cifs/cifs_dfs_ref.c: CIFS VFS: in cifs_dfs_do_automount as Xid: 1274 with uid: 1000
[ 2642.084955] fs/cifs/cifssmb.c: In GetDFSRefer the path \FIRE\Departments$\folder
[ 2642.084958] fs/cifs/transport.c: For smb_command 50
[ 2642.084960] fs/cifs/transport.c: Sending smb: total_len 120
[ 2642.085631] fs/cifs/connect.c: rfc1002 length 0xe2
[ 2642.085640] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=1051 state=4
[ 2642.085643] fs/cifs/cifssmb.c: Decoding GetDFSRefer response BCC: 167 Offset 56
[ 2642.085646] fs/cifs/cifssmb.c: num_referrals: 1 dfs flags: 0x2 ...
[ 2642.085647]
[ 2642.085652] fs/cifs/cifs_dfs_ref.c: CIFS VFS: leaving cifs_dfs_do_automount (xid = 1274) rc = 0
[ 2642.085654] fs/cifs/cifs_dfs_ref.c: DFS: ref path: \FIRE\Departments$\folder
[ 2642.085656] fs/cifs/cifs_dfs_ref.c: DFS: node path: \server\share$\folder
[ 2642.085658] fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0
[ 2642.085660] fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 22
[ 2642.085667] fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: resolved: server to 10.10.10.157
[ 2642.085678] fs/cifs/cifsfs.c: Devname: \\server\share$ flags: 0
[ 2642.085683] fs/cifs/connect.c: Domain name set
[ 2642.085686] fs/cifs/connect.c: prefix path /folder
[ 2642.085688] fs/cifs/connect.c: Username: shipclar
[ 2642.085691] fs/cifs/connect.c: file mode: 0x1ed dir mode: 0x1ed
[ 2642.085729] fs/cifs/connect.c: CIFS VFS: in cifs_mount as Xid: 1275 with uid: 1000
[ 2642.085732] fs/cifs/connect.c: UNC: \\server\share$ ip: 10.10.10.157
[ 2642.085742] fs/cifs/connect.c: Socket created
[ 2642.085744] fs/cifs/connect.c: sndbuf 16384 rcvbuf 87380 rcvtimeo 0x6d6
[ 2642.085962] fs/cifs/connect.c: CIFS VFS: in cifs_get_smb_ses as Xid: 1276 with uid: 1000
[ 2642.085964] fs/cifs/connect.c: Existing smb sess not found
[ 2642.085967] fs/cifs/cifssmb.c: secFlags 0x7
[ 2642.085968] fs/cifs/transport.c: For smb_command 114
[ 2642.085969] fs/cifs/transport.c: Sending smb: total_len 82
[ 2642.085983] fs/cifs/connect.c: Demultiplex PID: 4389
[ 2642.086143] fs/cifs/connect.c: rfc1002 length 0x67
[ 2642.086152] fs/cifs/transport.c: cifs_sync_mid_result: cmd=114 mid=1 state=4
[ 2642.086155] fs/cifs/cifssmb.c: Dialect: 2
[ 2642.086158] fs/cifs/cifssmb.c: negprot rc 0
[ 2642.086161] fs/cifs/connect.c: Security Mode: 0x3 Capabilities: 0x1e3fd TimeAdjust: 14400
[ 2642.086163] fs/cifs/sess.c: sess setup type 1
[ 2642.086182] fs/cifs/transport.c: For smb_command 115
[ 2642.086184] fs/cifs/transport.c: Sending smb: total_len 260
[ 2642.088296] fs/cifs/connect.c: rfc1002 length 0xef
[ 2642.088308] fs/cifs/transport.c: cifs_sync_mid_result: cmd=115 mid=2 state=4
[ 2642.088309] fs/cifs/misc.c: Null buffer passed to cifs_small_buf_release
[ 2642.088311] fs/cifs/sess.c: UID = 49152
[ 2642.088312] fs/cifs/sess.c: bleft 193
[ 2642.088314] fs/cifs/sess.c: serverOS=Windows Server (R) 2008 Standard 6001 Service Pack 1
[ 2642.088316] fs/cifs/sess.c: serverNOS=Windows Server (R) 2008 Standard 6.0
[ 2642.088318] fs/cifs/sess.c: serverDomain=TURTLE
[ 2642.088319] fs/cifs/sess.c: ssetup freeing small buf ffff880129c80e00
[ 2642.088320] fs/cifs/connect.c: CIFS Session Established successfully
[ 2642.088322] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_smb_ses (xid = 1276) rc = 0
[ 2642.088324] fs/cifs/connect.c: CIFS VFS: in cifs_get_tcon as Xid: 1277 with uid: 1000
[ 2642.088326] fs/cifs/transport.c: For smb_command 117
[ 2642.088327] fs/cifs/transport.c: Sending smb: total_len 80
[ 2642.088714] fs/cifs/connect.c: rfc1002 length 0x42
[ 2642.088722] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=3 state=4
[ 2642.088726] fs/cifs/connect.c: disk share connection
[ 2642.088729] fs/cifs/connect.c: nativeFileSystem=NTFS
[ 2642.088730] fs/cifs/connect.c: Tcon flags: 0x1
[ 2642.088733] fs/cifs/connect.c: CIFS VFS: leaving cifs_get_tcon (xid = 1277) rc = 0
[ 2642.088735] fs/cifs/connect.c: CIFS Tcon rc = 0
[ 2642.088737] fs/cifs/cifssmb.c: In QFSDeviceInfo
[ 2642.088740] fs/cifs/transport.c: For smb_command 50
[ 2642.088742] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.088906] fs/cifs/connect.c: rfc1002 length 0x44
[ 2642.088914] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=4 state=4
[ 2642.088917] fs/cifs/cifssmb.c: In QFSAttributeInfo
[ 2642.088919] fs/cifs/transport.c: For smb_command 50
[ 2642.088921] fs/cifs/transport.c: Sending smb: total_len 72
[ 2642.089074] fs/cifs/connect.c: rfc1002 length 0x50
[ 2642.089082] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=5 state=4
[ 2642.089085] fs/cifs/connect.c: build_unc_path_to_root: full_path=\\server\share$\folder
[ 2642.089093] fs/cifs/transport.c: For smb_command 117
[ 2642.089094] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.089263] fs/cifs/connect.c: rfc1002 length 0x3c
[ 2642.089271] fs/cifs/transport.c: cifs_sync_mid_result: cmd=117 mid=6 state=4
[ 2642.089274] fs/cifs/connect.c: CIFS Tcon rc = 0 ipc_tid = 24581
[ 2642.089276] fs/cifs/cifssmb.c: In GetDFSRefer the path \server\share$
[ 2642.089279] fs/cifs/transport.c: For smb_command 50
[ 2642.089280] fs/cifs/transport.c: Sending smb: total_len 98
[ 2642.089424] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.089427] fs/cifs/connect.c: invalid transact2 word count
[ 2642.089434] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=7 state=4
[ 2642.089438] Status code returned 0xc000019c NT_STATUS_FS_DRIVER_REQUIRED
[ 2642.089441] fs/cifs/netmisc.c: Mapping smb error code 0xc000019c to POSIX err -5
[ 2642.089443] fs/cifs/cifssmb.c: Send error in GetDFSRefer = -5
[ 2642.089447] fs/cifs/transport.c: For smb_command 50
[ 2642.089448] fs/cifs/transport.c: Sending smb: total_len 86
[ 2642.089693] fs/cifs/connect.c: rfc1002 length 0x9c
[ 2642.089701] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=8 state=4
[ 2642.089705] fs/cifs/connect.c: SPOT#2
[ 2642.089707] fs/cifs/connect.c: CIFS VFS: leaving cifs_mount (xid = 1275) rc = 0
[ 2642.089718] fs/cifs/inode.c: CIFS VFS: in cifs_root_iget as Xid: 1278 with uid: 1000
[ 2642.089720] fs/cifs/inode.c: Getting info on
[ 2642.089722] fs/cifs/transport.c: For smb_command 50
[ 2642.089724] fs/cifs/transport.c: Sending smb: total_len 78
[ 2642.090253] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.090256] fs/cifs/connect.c: invalid transact2 word count
[ 2642.090263] fs/cifs/transport.c: cifs_sync_mid_result: cmd=50 mid=9 state=4
[ 2642.090265] Status code returned 0xc0000022 NT_STATUS_ACCESS_DENIED
[ 2642.090269] fs/cifs/netmisc.c: Mapping smb error code 0xc0000022 to POSIX err -13
[ 2642.090271] fs/cifs/cifssmb.c: Send error in QPathInfo = -13
[ 2642.090273] CIFS VFS: cifs_read_super: get root inode failed
[ 2642.090278] fs/cifs/connect.c: cifs_put_tcon: tc_count=1
[ 2642.090279]
[ 2642.090281] fs/cifs/connect.c: CIFS VFS: in cifs_put_tcon as Xid: 1279 with uid: 1000
[ 2642.090283] fs/cifs/cifssmb.c: In tree disconnect
[ 2642.090285] fs/cifs/transport.c: For smb_command 113
[ 2642.090287] fs/cifs/transport.c: Sending smb: total_len 39
[ 2642.090462] fs/cifs/connect.c: rfc1002 length 0x27
[ 2642.090467] fs/cifs/transport.c: cifs_sync_mid_result: cmd=113 mid=10 state=4
[ 2642.090469] fs/cifs/connect.c: cifs_put_smb_ses: ses_count=1
[ 2642.090469]
[ 2642.090470] fs/cifs/connect.c: CIFS VFS: in cifs_put_smb_ses as Xid: 1280 with uid: 1000
[ 2642.090472] fs/cifs/cifssmb.c: In SMBLogoff for session disconnect
[ 2642.090473] fs/cifs/transport.c: For smb_command 116
[ 2642.090474] fs/cifs/transport.c: Sending smb: total_len 43
[ 2642.090815] fs/cifs/connect.c: rfc1002 length 0x2b
[ 2642.090823] fs/cifs/transport.c: cifs_sync_mid_result: cmd=116 mid=11 state=4
[ 2642.124026] fs/cifs/cifs_dfs_ref.c: cifs_dfs_do_automount: cifs_dfs_do_refmount:\server\share$\folder , mnt:fffffffffffffff3
[ 2642.124030] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_do_automount
[ 2642.124032] fs/cifs/cifs_dfs_ref.c: leaving cifs_dfs_d_automount [automount failed]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <4EA154FC.3090601-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2011-10-21 11:20 ` Terrence Shipclark
2011-10-23 10:30 ` sean finney
1 sibling, 0 replies; 10+ messages in thread
From: Terrence Shipclark @ 2011-10-21 11:20 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
On 11-10-21 07:18 AM, Terrence Shipclark wrote:
> Hello,
>
> This is my first time posting to this list, and I hope I am not breaking
> any rules.
>
> I have been attempting to get the cifs kernel modules to mount the
> win2k8 dfs at my workplace. I did finally manage to get
> the dfs to mount after modifying the kernel module with this small patch
>
> @@ -3109,6 +3112,7 @@
> cifs_sb, false);
> if (!refrc) {
> referral_walks_count++;
> + rc=0;
> goto try_mount_again;
> }
> }
>
> Although I dont 100% understand what I did, as I had a hard time
> following the goto statements, I have a feeling that on initial setup it
> would follow the DFS referral, however ultimately fail as it exited
> because rc was still set to -6.
>
> So now For my second problem.
>
> Within the dfs tree there is a referral to //server/share$/folder. My
> user has access to //server/share$/folder, however do not have access to
> //server/$share. While following the referral the cifs module does a
> QUERY_PATH_INFO on \\server\share$\folder, and then is followed up by a
> QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
> STATUS_ACCESS_DENIED from the server.
>
> Traversing the same path with smbclient \\server\share$ is never
> queried.Perhaps I am doing something wrong?
>
> I have been attempting to connect to this dfs from linux for about 2
> years,and this is the closest I have gotten, so any help would be
> appreciated.
>
> terry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <4EA154FC.3090601-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2011-10-21 11:20 ` Terrence Shipclark
@ 2011-10-23 10:30 ` sean finney
[not found] ` <20111023103003.GA6132-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
1 sibling, 1 reply; 10+ messages in thread
From: sean finney @ 2011-10-23 10:30 UTC (permalink / raw)
To: Terrence Shipclark; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Hello Terrence,
On Fri, Oct 21, 2011 at 07:18:20AM -0400, Terrence Shipclark wrote:
> I have been attempting to get the cifs kernel modules to mount the
> win2k8 dfs at my workplace. I did finally manage to get
> the dfs to mount after modifying the kernel module with this small patch
I believe this should already be fixed (in a more correct fashion) in >= 3.0.
> Within the dfs tree there is a referral to //server/share$/folder.
> My user has access to //server/share$/folder, however do not have
> access to
> //server/$share. While following the referral the cifs module does a
> QUERY_PATH_INFO on \\server\share$\folder, and then is followed up
> by a QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
> STATUS_ACCESS_DENIED from the server.
I've also noticed that the mounting process seems to query more than
it should, but I've taken the easy way out and asked the local windows
admin to add "traverse filesystem" and "read attributes" permissions on
the parent folders, which should be enough. I suspect that there is a
"real fix" to avoid this, but haven't looked too hard myself.
sean
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <20111023103003.GA6132-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
@ 2011-10-23 10:55 ` Jeff Layton
[not found] ` <20111023065534.566a0aad-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
0 siblings, 1 reply; 10+ messages in thread
From: Jeff Layton @ 2011-10-23 10:55 UTC (permalink / raw)
To: sean finney
Cc: Terrence Shipclark, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
Pavel Shilovsky
On Sun, 23 Oct 2011 12:30:03 +0200
sean finney <seanius-ADwgVSpYHhHR7s880joybQ@public.gmane.org> wrote:
> Hello Terrence,
>
> On Fri, Oct 21, 2011 at 07:18:20AM -0400, Terrence Shipclark wrote:
> > I have been attempting to get the cifs kernel modules to mount the
> > win2k8 dfs at my workplace. I did finally manage to get
> > the dfs to mount after modifying the kernel module with this small patch
>
> I believe this should already be fixed (in a more correct fashion) in >= 3.0.
>
> > Within the dfs tree there is a referral to //server/share$/folder.
> > My user has access to //server/share$/folder, however do not have
> > access to
> > //server/$share. While following the referral the cifs module does a
> > QUERY_PATH_INFO on \\server\share$\folder, and then is followed up
> > by a QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
> > STATUS_ACCESS_DENIED from the server.
>
> I've also noticed that the mounting process seems to query more than
> it should, but I've taken the easy way out and asked the local windows
> admin to add "traverse filesystem" and "read attributes" permissions on
> the parent folders, which should be enough. I suspect that there is a
> "real fix" to avoid this, but haven't looked too hard myself.
>
>
I believe this is a known bug...
3.0 got a patchset to allow superblocks to be shared, but that
regressed the above use case (mounting a directory that you have access
to but not the stuff below it).
Pavel had some patches that he was going to propose to fix it, but
discussion of them sort of fell off. Pavel, did you ever come up with
something that worked here?
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <20111023065534.566a0aad-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
@ 2011-10-23 19:10 ` Pavel Shilovsky
2011-10-24 7:35 ` sean finney
1 sibling, 0 replies; 10+ messages in thread
From: Pavel Shilovsky @ 2011-10-23 19:10 UTC (permalink / raw)
To: Jeff Layton
Cc: sean finney, Terrence Shipclark,
linux-cifs-u79uwXL29TY76Z2rM5mHXA
2011/10/23 Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>:
> On Sun, 23 Oct 2011 12:30:03 +0200
> sean finney <seanius-ADwgVSpYHhHR7s880joybQ@public.gmane.org> wrote:
>
>> Hello Terrence,
>>
>> On Fri, Oct 21, 2011 at 07:18:20AM -0400, Terrence Shipclark wrote:
>> > I have been attempting to get the cifs kernel modules to mount the
>> > win2k8 dfs at my workplace. I did finally manage to get
>> > the dfs to mount after modifying the kernel module with this small patch
>>
>> I believe this should already be fixed (in a more correct fashion) in >= 3.0.
>>
>> > Within the dfs tree there is a referral to //server/share$/folder.
>> > My user has access to //server/share$/folder, however do not have
>> > access to
>> > //server/$share. While following the referral the cifs module does a
>> > QUERY_PATH_INFO on \\server\share$\folder, and then is followed up
>> > by a QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
>> > STATUS_ACCESS_DENIED from the server.
>>
>> I've also noticed that the mounting process seems to query more than
>> it should, but I've taken the easy way out and asked the local windows
>> admin to add "traverse filesystem" and "read attributes" permissions on
>> the parent folders, which should be enough. I suspect that there is a
>> "real fix" to avoid this, but haven't looked too hard myself.
>>
>>
>
> I believe this is a known bug...
>
> 3.0 got a patchset to allow superblocks to be shared, but that
> regressed the above use case (mounting a directory that you have access
> to but not the stuff below it).
>
> Pavel had some patches that he was going to propose to fix it, but
> discussion of them sort of fell off. Pavel, did you ever come up with
> something that worked here?
>
We had the discussion in "[PATCH] CIFS: Fix NT_STATUS_ACCESS_DENIED
for mounts with prefixpath option" thread in this list where I
proposed a patch that fixes it. Later I found two bugs in it but
didn't send another (right) version because we decided to fix the
permission problem another way.
After that I didn't have time to work on it. So, I am going to give it
more time when we finished with merging lock patchset and SMB2 patches
for 3.2.
Also, if you are interested, I can send you the right version of the
patch I've already posted.
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <20111023065534.566a0aad-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-10-23 19:10 ` Pavel Shilovsky
@ 2011-10-24 7:35 ` sean finney
[not found] ` <20111024073534.GB7086-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
1 sibling, 1 reply; 10+ messages in thread
From: sean finney @ 2011-10-24 7:35 UTC (permalink / raw)
To: Jeff Layton, Pavel Shilovsky
Cc: Terrence Shipclark, linux-cifs-u79uwXL29TY76Z2rM5mHXA
Hi Jeff, Pavel,
On Sun, Oct 23, 2011 at 06:55:34AM -0400, Jeff Layton wrote:
> 3.0 got a patchset to allow superblocks to be shared, but that
> regressed the above use case (mounting a directory that you have access
> to but not the stuff below it).
I also seem to recall there being a problem with the request on the target
directory (existing behavior, not a regression), that it used the SMB
QueryFileAllInfo or whatever it's called, instead of just QueryFileInfo,
which is the motivation for needing the "read file attributes" permission.
My memory is a bit hazy here, but i have a vague recollection of looking
at smbclient using the same credentials only doing a QueryFileInfo and
succeeding.
On Sun, Oct 23, 2011 at 11:10:01PM +0400, Pavel Shilovsky wrote:
> Also, if you are interested, I can send you the right version of the
> patch I've already posted.
Please do :) I can't promise that I have any time to look at it but
it would be good to have regardless.
sean
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <20111024073534.GB7086-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
@ 2011-11-01 18:13 ` Pavel Shilovsky
[not found] ` <1320171185-11150-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Shilovsky @ 2011-11-01 18:13 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
Sorry for so long delay on this. Here is the fixed version of the patch:
[PATCH] CIFS: Fix NT_STATUS_ACCESS_DENIED for mounts with prefixpath option
but I found out one use case where it doesn't work right:
1) mount //server/share/a/b/ test
2) mount //server/share/ test2
3) stat test2/a/b - return wrong inode number (autodisable server inode number happens)
In the same time if I add "ls test2" before step #3 it works! May be VFS can't
handle negative dentry with children in this case, but I am not sure.
Reorganize code and make it send qpath info request only for a full
path (//server/share/prefixpath) rather than request for every path
compoment. In this case we end up with negative dentries for all
components except full one and we will instantiate them later if
such a mount is requested.
Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
---
fs/cifs/cifsfs.c | 138 +++++++++++++++++++++++++++++++--------------------
fs/cifs/cifsfs.h | 3 +-
fs/cifs/cifsglob.h | 6 ++
fs/cifs/dir.c | 3 +-
fs/cifs/inode.c | 7 ++-
fs/cifs/readdir.c | 43 ++++++++++------
6 files changed, 124 insertions(+), 76 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8f1fe32..a188be1 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -90,14 +90,13 @@ extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
extern mempool_t *cifs_mid_poolp;
-static int
+static void
cifs_read_super(struct super_block *sb)
{
- struct inode *inode;
- struct cifs_sb_info *cifs_sb;
- int rc = 0;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- cifs_sb = CIFS_SB(sb);
+ /* BB should we make this contingent on mount parm? */
+ sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
sb->s_flags |= MS_POSIXACL;
@@ -115,26 +114,6 @@ cifs_read_super(struct super_block *sb)
sb->s_bdi = &cifs_sb->bdi;
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
- inode = cifs_root_iget(sb);
-
- if (IS_ERR(inode)) {
- rc = PTR_ERR(inode);
- inode = NULL;
- goto out_no_root;
- }
-
- sb->s_root = d_alloc_root(inode);
-
- if (!sb->s_root) {
- rc = -ENOMEM;
- goto out_no_root;
- }
-
- /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
- if (cifs_sb_master_tcon(cifs_sb)->nocase)
- sb->s_d_op = &cifs_ci_dentry_ops;
- else
- sb->s_d_op = &cifs_dentry_ops;
#ifdef CONFIG_CIFS_NFSD_EXPORT
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
@@ -143,14 +122,7 @@ cifs_read_super(struct super_block *sb)
}
#endif /* CONFIG_CIFS_NFSD_EXPORT */
- return 0;
-
-out_no_root:
- cERROR(1, "cifs_read_super: get root inode failed");
- if (inode)
- iput(inode);
-
- return rc;
+ sb->s_flags |= MS_ACTIVE;
}
static void cifs_kill_sb(struct super_block *sb)
@@ -528,6 +500,17 @@ static const struct super_operations cifs_super_ops = {
#endif
};
+static struct dentry *
+cifs_alloc_root(struct super_block *sb)
+{
+ struct qstr q;
+
+ q.name = "/";
+ q.len = 1;
+ q.hash = full_name_hash(q.name, q.len);
+ return d_alloc_pseudo(sb, &q);
+}
+
/*
* Get root dentry from superblock according to prefix path mount option.
* Return dentry with refcount + 1 on success and NULL otherwise.
@@ -535,8 +518,10 @@ static const struct super_operations cifs_super_ops = {
static struct dentry *
cifs_get_root(struct smb_vol *vol, struct super_block *sb)
{
- struct dentry *dentry;
+ struct dentry *dentry, *found;
+ struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct qstr q;
char *full_path = NULL;
char *s, *p;
char sep;
@@ -548,20 +533,30 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
cFYI(1, "Get root dentry for %s", full_path);
+ if (!sb->s_root) {
+ sb->s_root = cifs_alloc_root(sb);
+ if (IS_ERR(sb->s_root)) {
+ dentry = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+
+ /*
+ * do that *after* cifs_alloc_root() - we want NULL ->d_op for
+ * root here
+ */
+ if (cifs_sb_master_tcon(cifs_sb)->nocase)
+ sb->s_d_op = &cifs_ci_dentry_ops;
+ else
+ sb->s_d_op = &cifs_dentry_ops;
+ }
+
sep = CIFS_DIR_SEP(cifs_sb);
dentry = dget(sb->s_root);
p = s = full_path;
do {
- struct inode *dir = dentry->d_inode;
struct dentry *child;
- if (!dir) {
- dput(dentry);
- dentry = ERR_PTR(-ENOENT);
- break;
- }
-
/* skip separators */
while (*s == sep)
s++;
@@ -572,12 +567,55 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
while (*s && *s != sep)
s++;
- mutex_lock(&dir->i_mutex);
- child = lookup_one_len(p, dentry, s - p);
- mutex_unlock(&dir->i_mutex);
+ q.name = p;
+ q.len = s - p;
+ if (dentry->d_flags & DCACHE_OP_HASH)
+ dentry->d_op->d_hash(dentry, dentry->d_inode, &q);
+ else
+ q.hash = full_name_hash(q.name, q.len);
+
+ child = d_lookup(dentry, &q);
+ if (!child) {
+ child = d_alloc(dentry, &q);
+ if (IS_ERR(child)) {
+ dput(dentry);
+ dentry = ERR_CAST(child);
+ break;
+ }
+ d_rehash(child);
+ }
dput(dentry);
dentry = child;
} while (!IS_ERR(dentry));
+
+ if (IS_ERR(dentry))
+ goto out;
+
+ mutex_lock(&cifs_root_mutex);
+
+ if (dentry->d_parent->d_inode)
+ mutex_lock(&dentry->d_parent->d_inode->i_mutex);
+
+ if (!dentry->d_inode) {
+ inode = cifs_mntroot_iget(sb, full_path);
+ if (IS_ERR(inode)) {
+ dput(dentry);
+ dentry = ERR_CAST(inode);
+ goto out;
+ }
+
+ found = d_instantiate_unique(dentry, inode);
+ if (found) {
+ dput(dentry);
+ dentry = found;
+ }
+ }
+
+ if (dentry->d_parent->d_inode)
+ mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
+
+ mutex_unlock(&cifs_root_mutex);
+out:
kfree(full_path);
return dentry;
}
@@ -644,16 +682,7 @@ cifs_do_mount(struct file_system_type *fs_type,
cifs_umount(cifs_sb);
} else {
sb->s_flags = flags;
- /* BB should we make this contingent on mount parm? */
- sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
-
- rc = cifs_read_super(sb);
- if (rc) {
- root = ERR_PTR(rc);
- goto out_super;
- }
-
- sb->s_flags |= MS_ACTIVE;
+ cifs_read_super(sb);
}
root = cifs_get_root(volume_info, sb);
@@ -1112,6 +1141,7 @@ init_cifs(void)
spin_lock_init(&cifs_tcp_ses_lock);
spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);
+ mutex_init(&cifs_root_mutex);
if (cifs_max_pending < 2) {
cifs_max_pending = 2;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 30ff560..cf28150 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -43,7 +43,8 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf;
/* Functions related to inodes */
extern const struct inode_operations cifs_dir_inode_ops;
-extern struct inode *cifs_root_iget(struct super_block *);
+extern struct inode *cifs_mntroot_iget(struct super_block *sb,
+ const char *full_path);
extern int cifs_create(struct inode *, struct dentry *, int,
struct nameidata *);
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 8238aa1..67f6852 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -958,6 +958,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
*/
GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
+/*
+ * This lock protects root dentry in cifs_get_root from being instantiated
+ * twice.
+ */
+GLOBAL_EXTERN struct mutex cifs_root_mutex;
+
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
/* Outstanding dir notify requests */
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d7eeb9d..d6b3319 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -553,6 +553,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
if (direntry->d_inode != NULL) {
cFYI(1, "non-NULL inode in lookup");
+ newInode = direntry->d_inode;
} else {
cFYI(1, "NULL inode in lookup");
}
@@ -596,7 +597,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
rc = cifs_get_inode_info(&newInode, full_path, NULL,
parent_dir_inode->i_sb, xid, NULL);
- if ((rc == 0) && (newInode != NULL)) {
+ if ((rc == 0) && (newInode != NULL) && !direntry->d_inode) {
d_add(direntry, newInode);
if (posix_open) {
filp = lookup_instantiate_filp(nd, direntry,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 2c50bd2..7b7fccd 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -878,7 +878,7 @@ retry_iget5_locked:
}
/* gets root inode */
-struct inode *cifs_root_iget(struct super_block *sb)
+struct inode *cifs_mntroot_iget(struct super_block *sb, const char *full_path)
{
int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -888,9 +888,10 @@ struct inode *cifs_root_iget(struct super_block *sb)
xid = GetXid();
if (tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
+ rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
else
- rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
+ rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid,
+ NULL);
if (!inode) {
inode = ERR_PTR(rc);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 5de03ec..b2f8851 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -65,10 +65,8 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
}
#endif /* DEBUG2 */
-/*
- * Find the dentry that matches "name". If there isn't one, create one. If it's
- * a negative dentry or the uniqueid changed, then drop it and recreate it.
- */
+
+/* Find the dentry that matches "name". If there isn't one, create one. */
static struct dentry *
cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
struct cifs_fattr *fattr)
@@ -84,32 +82,38 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
else
name->hash = full_name_hash(name->name, name->len);
+ mutex_lock(&cifs_root_mutex);
+
dentry = d_lookup(parent, name);
if (dentry) {
/* FIXME: check for inode number changes? */
if (dentry->d_inode != NULL)
- return dentry;
- d_drop(dentry);
- dput(dentry);
+ goto out;
+ } else {
+ dentry = d_alloc(parent, name);
+ if (dentry == NULL)
+ goto out;
+ d_rehash(dentry);
}
- dentry = d_alloc(parent, name);
- if (dentry == NULL)
- return NULL;
-
inode = cifs_iget(sb, fattr);
if (!inode) {
dput(dentry);
- return NULL;
+ dentry = NULL;
+ goto out;
}
- alias = d_materialise_unique(dentry, inode);
+ alias = d_instantiate_unique(dentry, inode);
if (alias != NULL) {
dput(dentry);
- if (IS_ERR(alias))
- return NULL;
+ if (IS_ERR(alias)) {
+ dentry = NULL;
+ goto out;
+ }
dentry = alias;
}
+out:
+ mutex_unlock(&cifs_root_mutex);
return dentry;
}
@@ -708,6 +712,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
char *tmp_buf = NULL;
char *end_of_smb;
unsigned int max_len;
+ ino_t ino;
xid = GetXid();
@@ -732,8 +737,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
}
file->f_pos++;
case 1:
- if (filldir(direntry, "..", 2, file->f_pos,
- parent_ino(file->f_path.dentry), DT_DIR) < 0) {
+ if (!file->f_path.dentry->d_parent->d_inode) {
+ cFYI(1, "parent dir is negative, filling as current");
+ ino = file->f_path.dentry->d_inode->i_ino;
+ } else
+ ino = parent_ino(file->f_path.dentry);
+ if (filldir(direntry, "..", 2, file->f_pos, ino, DT_DIR) < 0) {
cERROR(1, "Filldir for parent dir failed");
rc = -ENOMEM;
break;
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <1320171185-11150-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
@ 2011-11-01 19:56 ` Pavel Shilovsky
[not found] ` <CAKywueRjR+UNg98odoe8x2WmnqdiCtEa_UgwnKt-8AEi0XRFdQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Shilovsky @ 2011-11-01 19:56 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
2011/11/1 Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>:
> Sorry for so long delay on this. Here is the fixed version of the patch:
>
> [PATCH] CIFS: Fix NT_STATUS_ACCESS_DENIED for mounts with prefixpath option
>
> but I found out one use case where it doesn't work right:
>
> 1) mount //server/share/a/b/ test
> 2) mount //server/share/ test2
> 3) stat test2/a/b - return wrong inode number (autodisable server inode number happens)
>
> In the same time if I add "ls test2" before step #3 it works! May be VFS can't
> handle negative dentry with children in this case, but I am not sure.
>
> Reorganize code and make it send qpath info request only for a full
> path (//server/share/prefixpath) rather than request for every path
> compoment. In this case we end up with negative dentries for all
> components except full one and we will instantiate them later if
> such a mount is requested.
>
> Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
> ---
> fs/cifs/cifsfs.c | 138 +++++++++++++++++++++++++++++++--------------------
> fs/cifs/cifsfs.h | 3 +-
> fs/cifs/cifsglob.h | 6 ++
> fs/cifs/dir.c | 3 +-
> fs/cifs/inode.c | 7 ++-
> fs/cifs/readdir.c | 43 ++++++++++------
> 6 files changed, 124 insertions(+), 76 deletions(-)
>
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 8f1fe32..a188be1 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -90,14 +90,13 @@ extern mempool_t *cifs_sm_req_poolp;
> extern mempool_t *cifs_req_poolp;
> extern mempool_t *cifs_mid_poolp;
>
> -static int
> +static void
> cifs_read_super(struct super_block *sb)
> {
> - struct inode *inode;
> - struct cifs_sb_info *cifs_sb;
> - int rc = 0;
> + struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>
> - cifs_sb = CIFS_SB(sb);
> + /* BB should we make this contingent on mount parm? */
> + sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
>
> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
> sb->s_flags |= MS_POSIXACL;
> @@ -115,26 +114,6 @@ cifs_read_super(struct super_block *sb)
> sb->s_bdi = &cifs_sb->bdi;
> sb->s_blocksize = CIFS_MAX_MSGSIZE;
> sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
> - inode = cifs_root_iget(sb);
> -
> - if (IS_ERR(inode)) {
> - rc = PTR_ERR(inode);
> - inode = NULL;
> - goto out_no_root;
> - }
> -
> - sb->s_root = d_alloc_root(inode);
> -
> - if (!sb->s_root) {
> - rc = -ENOMEM;
> - goto out_no_root;
> - }
> -
> - /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
> - if (cifs_sb_master_tcon(cifs_sb)->nocase)
> - sb->s_d_op = &cifs_ci_dentry_ops;
> - else
> - sb->s_d_op = &cifs_dentry_ops;
>
> #ifdef CONFIG_CIFS_NFSD_EXPORT
> if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
> @@ -143,14 +122,7 @@ cifs_read_super(struct super_block *sb)
> }
> #endif /* CONFIG_CIFS_NFSD_EXPORT */
>
> - return 0;
> -
> -out_no_root:
> - cERROR(1, "cifs_read_super: get root inode failed");
> - if (inode)
> - iput(inode);
> -
> - return rc;
> + sb->s_flags |= MS_ACTIVE;
> }
>
> static void cifs_kill_sb(struct super_block *sb)
> @@ -528,6 +500,17 @@ static const struct super_operations cifs_super_ops = {
> #endif
> };
>
> +static struct dentry *
> +cifs_alloc_root(struct super_block *sb)
> +{
> + struct qstr q;
> +
> + q.name = "/";
> + q.len = 1;
> + q.hash = full_name_hash(q.name, q.len);
> + return d_alloc_pseudo(sb, &q);
> +}
> +
> /*
> * Get root dentry from superblock according to prefix path mount option.
> * Return dentry with refcount + 1 on success and NULL otherwise.
> @@ -535,8 +518,10 @@ static const struct super_operations cifs_super_ops = {
> static struct dentry *
> cifs_get_root(struct smb_vol *vol, struct super_block *sb)
> {
> - struct dentry *dentry;
> + struct dentry *dentry, *found;
> + struct inode *inode;
> struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> + struct qstr q;
> char *full_path = NULL;
> char *s, *p;
> char sep;
> @@ -548,20 +533,30 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>
> cFYI(1, "Get root dentry for %s", full_path);
>
> + if (!sb->s_root) {
> + sb->s_root = cifs_alloc_root(sb);
> + if (IS_ERR(sb->s_root)) {
> + dentry = ERR_PTR(-ENOMEM);
> + goto out;
> + }
> +
> + /*
> + * do that *after* cifs_alloc_root() - we want NULL ->d_op for
> + * root here
> + */
> + if (cifs_sb_master_tcon(cifs_sb)->nocase)
> + sb->s_d_op = &cifs_ci_dentry_ops;
> + else
> + sb->s_d_op = &cifs_dentry_ops;
> + }
> +
> sep = CIFS_DIR_SEP(cifs_sb);
> dentry = dget(sb->s_root);
> p = s = full_path;
>
> do {
> - struct inode *dir = dentry->d_inode;
> struct dentry *child;
>
> - if (!dir) {
> - dput(dentry);
> - dentry = ERR_PTR(-ENOENT);
> - break;
> - }
> -
> /* skip separators */
> while (*s == sep)
> s++;
> @@ -572,12 +567,55 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
> while (*s && *s != sep)
> s++;
>
> - mutex_lock(&dir->i_mutex);
> - child = lookup_one_len(p, dentry, s - p);
> - mutex_unlock(&dir->i_mutex);
> + q.name = p;
> + q.len = s - p;
> + if (dentry->d_flags & DCACHE_OP_HASH)
> + dentry->d_op->d_hash(dentry, dentry->d_inode, &q);
> + else
> + q.hash = full_name_hash(q.name, q.len);
> +
> + child = d_lookup(dentry, &q);
> + if (!child) {
> + child = d_alloc(dentry, &q);
> + if (IS_ERR(child)) {
> + dput(dentry);
> + dentry = ERR_CAST(child);
> + break;
> + }
> + d_rehash(child);
> + }
> dput(dentry);
> dentry = child;
> } while (!IS_ERR(dentry));
> +
> + if (IS_ERR(dentry))
> + goto out;
> +
> + mutex_lock(&cifs_root_mutex);
> +
> + if (dentry->d_parent->d_inode)
> + mutex_lock(&dentry->d_parent->d_inode->i_mutex);
> +
> + if (!dentry->d_inode) {
> + inode = cifs_mntroot_iget(sb, full_path);
> + if (IS_ERR(inode)) {
> + dput(dentry);
> + dentry = ERR_CAST(inode);
> + goto out;
> + }
> +
> + found = d_instantiate_unique(dentry, inode);
> + if (found) {
> + dput(dentry);
> + dentry = found;
> + }
> + }
> +
> + if (dentry->d_parent->d_inode)
> + mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
> +
> + mutex_unlock(&cifs_root_mutex);
> +out:
> kfree(full_path);
> return dentry;
> }
> @@ -644,16 +682,7 @@ cifs_do_mount(struct file_system_type *fs_type,
> cifs_umount(cifs_sb);
> } else {
> sb->s_flags = flags;
> - /* BB should we make this contingent on mount parm? */
> - sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
> -
> - rc = cifs_read_super(sb);
> - if (rc) {
> - root = ERR_PTR(rc);
> - goto out_super;
> - }
> -
> - sb->s_flags |= MS_ACTIVE;
> + cifs_read_super(sb);
> }
>
> root = cifs_get_root(volume_info, sb);
> @@ -1112,6 +1141,7 @@ init_cifs(void)
> spin_lock_init(&cifs_tcp_ses_lock);
> spin_lock_init(&cifs_file_list_lock);
> spin_lock_init(&GlobalMid_Lock);
> + mutex_init(&cifs_root_mutex);
>
> if (cifs_max_pending < 2) {
> cifs_max_pending = 2;
> diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
> index 30ff560..cf28150 100644
> --- a/fs/cifs/cifsfs.h
> +++ b/fs/cifs/cifsfs.h
> @@ -43,7 +43,8 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf;
>
> /* Functions related to inodes */
> extern const struct inode_operations cifs_dir_inode_ops;
> -extern struct inode *cifs_root_iget(struct super_block *);
> +extern struct inode *cifs_mntroot_iget(struct super_block *sb,
> + const char *full_path);
> extern int cifs_create(struct inode *, struct dentry *, int,
> struct nameidata *);
> extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 8238aa1..67f6852 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -958,6 +958,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
> */
> GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
>
> +/*
> + * This lock protects root dentry in cifs_get_root from being instantiated
> + * twice.
> + */
> +GLOBAL_EXTERN struct mutex cifs_root_mutex;
> +
> #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
> /* Outstanding dir notify requests */
> GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> index d7eeb9d..d6b3319 100644
> --- a/fs/cifs/dir.c
> +++ b/fs/cifs/dir.c
> @@ -553,6 +553,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
>
> if (direntry->d_inode != NULL) {
> cFYI(1, "non-NULL inode in lookup");
> + newInode = direntry->d_inode;
this and ...
> } else {
> cFYI(1, "NULL inode in lookup");
> }
> @@ -596,7 +597,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> rc = cifs_get_inode_info(&newInode, full_path, NULL,
> parent_dir_inode->i_sb, xid, NULL);
>
> - if ((rc == 0) && (newInode != NULL)) {
> + if ((rc == 0) && (newInode != NULL) && !direntry->d_inode) {
... this doesn't make sense - I made it for testing purpose only and
forgot to remove. Since this patch isn't going to be a candidate to
merge, seems no need to respin it.
> d_add(direntry, newInode);
> if (posix_open) {
> filp = lookup_instantiate_filp(nd, direntry,
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index 2c50bd2..7b7fccd 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -878,7 +878,7 @@ retry_iget5_locked:
> }
>
> /* gets root inode */
> -struct inode *cifs_root_iget(struct super_block *sb)
> +struct inode *cifs_mntroot_iget(struct super_block *sb, const char *full_path)
> {
> int xid;
> struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> @@ -888,9 +888,10 @@ struct inode *cifs_root_iget(struct super_block *sb)
>
> xid = GetXid();
> if (tcon->unix_ext)
> - rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
> + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
> else
> - rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
> + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid,
> + NULL);
>
> if (!inode) {
> inode = ERR_PTR(rc);
> diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
> index 5de03ec..b2f8851 100644
> --- a/fs/cifs/readdir.c
> +++ b/fs/cifs/readdir.c
> @@ -65,10 +65,8 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
> }
> #endif /* DEBUG2 */
>
> -/*
> - * Find the dentry that matches "name". If there isn't one, create one. If it's
> - * a negative dentry or the uniqueid changed, then drop it and recreate it.
> - */
> +
> +/* Find the dentry that matches "name". If there isn't one, create one. */
> static struct dentry *
> cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
> struct cifs_fattr *fattr)
> @@ -84,32 +82,38 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
> else
> name->hash = full_name_hash(name->name, name->len);
>
> + mutex_lock(&cifs_root_mutex);
> +
> dentry = d_lookup(parent, name);
> if (dentry) {
> /* FIXME: check for inode number changes? */
> if (dentry->d_inode != NULL)
> - return dentry;
> - d_drop(dentry);
> - dput(dentry);
> + goto out;
> + } else {
> + dentry = d_alloc(parent, name);
> + if (dentry == NULL)
> + goto out;
> + d_rehash(dentry);
> }
>
> - dentry = d_alloc(parent, name);
> - if (dentry == NULL)
> - return NULL;
> -
> inode = cifs_iget(sb, fattr);
> if (!inode) {
> dput(dentry);
> - return NULL;
> + dentry = NULL;
> + goto out;
> }
>
> - alias = d_materialise_unique(dentry, inode);
> + alias = d_instantiate_unique(dentry, inode);
> if (alias != NULL) {
> dput(dentry);
> - if (IS_ERR(alias))
> - return NULL;
> + if (IS_ERR(alias)) {
> + dentry = NULL;
> + goto out;
> + }
> dentry = alias;
> }
> +out:
> + mutex_unlock(&cifs_root_mutex);
>
> return dentry;
> }
> @@ -708,6 +712,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
> char *tmp_buf = NULL;
> char *end_of_smb;
> unsigned int max_len;
> + ino_t ino;
>
> xid = GetXid();
>
> @@ -732,8 +737,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
> }
> file->f_pos++;
> case 1:
> - if (filldir(direntry, "..", 2, file->f_pos,
> - parent_ino(file->f_path.dentry), DT_DIR) < 0) {
> + if (!file->f_path.dentry->d_parent->d_inode) {
> + cFYI(1, "parent dir is negative, filling as current");
> + ino = file->f_path.dentry->d_inode->i_ino;
> + } else
> + ino = parent_ino(file->f_path.dentry);
> + if (filldir(direntry, "..", 2, file->f_pos, ino, DT_DIR) < 0) {
> cERROR(1, "Filldir for parent dir failed");
> rc = -ENOMEM;
> break;
> --
> 1.7.1
>
>
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
[not found] ` <CAKywueRjR+UNg98odoe8x2WmnqdiCtEa_UgwnKt-8AEi0XRFdQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-11-10 13:24 ` Jeff Layton
2011-11-10 13:38 ` Pavel Shilovsky
0 siblings, 1 reply; 10+ messages in thread
From: Jeff Layton @ 2011-11-10 13:24 UTC (permalink / raw)
To: Pavel Shilovsky
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
On Tue, 1 Nov 2011 22:56:18 +0300
Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
> 2011/11/1 Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>:
> > Sorry for so long delay on this. Here is the fixed version of the patch:
> >
> > [PATCH] CIFS: Fix NT_STATUS_ACCESS_DENIED for mounts with prefixpath option
> >
> > but I found out one use case where it doesn't work right:
> >
> > 1) mount //server/share/a/b/ test
> > 2) mount //server/share/ test2
> > 3) stat test2/a/b - return wrong inode number (autodisable server inode number happens)
> >
> > In the same time if I add "ls test2" before step #3 it works! May be VFS can't
> > handle negative dentry with children in this case, but I am not sure.
> >
> > Reorganize code and make it send qpath info request only for a full
> > path (//server/share/prefixpath) rather than request for every path
> > compoment. In this case we end up with negative dentries for all
> > components except full one and we will instantiate them later if
> > such a mount is requested.
> >
> > Signed-off-by: Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
> > ---
> > fs/cifs/cifsfs.c | 138 +++++++++++++++++++++++++++++++--------------------
> > fs/cifs/cifsfs.h | 3 +-
> > fs/cifs/cifsglob.h | 6 ++
> > fs/cifs/dir.c | 3 +-
> > fs/cifs/inode.c | 7 ++-
> > fs/cifs/readdir.c | 43 ++++++++++------
> > 6 files changed, 124 insertions(+), 76 deletions(-)
> >
> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > index 8f1fe32..a188be1 100644
> > --- a/fs/cifs/cifsfs.c
> > +++ b/fs/cifs/cifsfs.c
> > @@ -90,14 +90,13 @@ extern mempool_t *cifs_sm_req_poolp;
> > extern mempool_t *cifs_req_poolp;
> > extern mempool_t *cifs_mid_poolp;
> >
> > -static int
> > +static void
> > cifs_read_super(struct super_block *sb)
> > {
> > - struct inode *inode;
> > - struct cifs_sb_info *cifs_sb;
> > - int rc = 0;
> > + struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> >
> > - cifs_sb = CIFS_SB(sb);
> > + /* BB should we make this contingent on mount parm? */
> > + sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
> >
> > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
> > sb->s_flags |= MS_POSIXACL;
> > @@ -115,26 +114,6 @@ cifs_read_super(struct super_block *sb)
> > sb->s_bdi = &cifs_sb->bdi;
> > sb->s_blocksize = CIFS_MAX_MSGSIZE;
> > sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
> > - inode = cifs_root_iget(sb);
> > -
> > - if (IS_ERR(inode)) {
> > - rc = PTR_ERR(inode);
> > - inode = NULL;
> > - goto out_no_root;
> > - }
> > -
> > - sb->s_root = d_alloc_root(inode);
> > -
> > - if (!sb->s_root) {
> > - rc = -ENOMEM;
> > - goto out_no_root;
> > - }
> > -
> > - /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
> > - if (cifs_sb_master_tcon(cifs_sb)->nocase)
> > - sb->s_d_op = &cifs_ci_dentry_ops;
> > - else
> > - sb->s_d_op = &cifs_dentry_ops;
> >
> > #ifdef CONFIG_CIFS_NFSD_EXPORT
> > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
> > @@ -143,14 +122,7 @@ cifs_read_super(struct super_block *sb)
> > }
> > #endif /* CONFIG_CIFS_NFSD_EXPORT */
> >
> > - return 0;
> > -
> > -out_no_root:
> > - cERROR(1, "cifs_read_super: get root inode failed");
> > - if (inode)
> > - iput(inode);
> > -
> > - return rc;
> > + sb->s_flags |= MS_ACTIVE;
> > }
> >
> > static void cifs_kill_sb(struct super_block *sb)
> > @@ -528,6 +500,17 @@ static const struct super_operations cifs_super_ops = {
> > #endif
> > };
> >
> > +static struct dentry *
> > +cifs_alloc_root(struct super_block *sb)
> > +{
> > + struct qstr q;
> > +
> > + q.name = "/";
> > + q.len = 1;
> > + q.hash = full_name_hash(q.name, q.len);
> > + return d_alloc_pseudo(sb, &q);
> > +}
> > +
> > /*
> > * Get root dentry from superblock according to prefix path mount option.
> > * Return dentry with refcount + 1 on success and NULL otherwise.
> > @@ -535,8 +518,10 @@ static const struct super_operations cifs_super_ops = {
> > static struct dentry *
> > cifs_get_root(struct smb_vol *vol, struct super_block *sb)
> > {
> > - struct dentry *dentry;
> > + struct dentry *dentry, *found;
> > + struct inode *inode;
> > struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> > + struct qstr q;
> > char *full_path = NULL;
> > char *s, *p;
> > char sep;
> > @@ -548,20 +533,30 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
> >
> > cFYI(1, "Get root dentry for %s", full_path);
> >
> > + if (!sb->s_root) {
> > + sb->s_root = cifs_alloc_root(sb);
> > + if (IS_ERR(sb->s_root)) {
> > + dentry = ERR_PTR(-ENOMEM);
> > + goto out;
> > + }
> > +
> > + /*
> > + * do that *after* cifs_alloc_root() - we want NULL ->d_op for
> > + * root here
> > + */
> > + if (cifs_sb_master_tcon(cifs_sb)->nocase)
> > + sb->s_d_op = &cifs_ci_dentry_ops;
> > + else
> > + sb->s_d_op = &cifs_dentry_ops;
> > + }
> > +
> > sep = CIFS_DIR_SEP(cifs_sb);
> > dentry = dget(sb->s_root);
> > p = s = full_path;
> >
> > do {
> > - struct inode *dir = dentry->d_inode;
> > struct dentry *child;
> >
> > - if (!dir) {
> > - dput(dentry);
> > - dentry = ERR_PTR(-ENOENT);
> > - break;
> > - }
> > -
> > /* skip separators */
> > while (*s == sep)
> > s++;
> > @@ -572,12 +567,55 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
> > while (*s && *s != sep)
> > s++;
> >
> > - mutex_lock(&dir->i_mutex);
> > - child = lookup_one_len(p, dentry, s - p);
> > - mutex_unlock(&dir->i_mutex);
> > + q.name = p;
> > + q.len = s - p;
> > + if (dentry->d_flags & DCACHE_OP_HASH)
> > + dentry->d_op->d_hash(dentry, dentry->d_inode, &q);
> > + else
> > + q.hash = full_name_hash(q.name, q.len);
> > +
> > + child = d_lookup(dentry, &q);
> > + if (!child) {
> > + child = d_alloc(dentry, &q);
> > + if (IS_ERR(child)) {
> > + dput(dentry);
> > + dentry = ERR_CAST(child);
> > + break;
> > + }
> > + d_rehash(child);
> > + }
> > dput(dentry);
> > dentry = child;
> > } while (!IS_ERR(dentry));
> > +
> > + if (IS_ERR(dentry))
> > + goto out;
> > +
> > + mutex_lock(&cifs_root_mutex);
> > +
> > + if (dentry->d_parent->d_inode)
> > + mutex_lock(&dentry->d_parent->d_inode->i_mutex);
> > +
> > + if (!dentry->d_inode) {
> > + inode = cifs_mntroot_iget(sb, full_path);
> > + if (IS_ERR(inode)) {
> > + dput(dentry);
> > + dentry = ERR_CAST(inode);
> > + goto out;
> > + }
> > +
> > + found = d_instantiate_unique(dentry, inode);
> > + if (found) {
> > + dput(dentry);
> > + dentry = found;
> > + }
> > + }
> > +
> > + if (dentry->d_parent->d_inode)
> > + mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
> > +
> > + mutex_unlock(&cifs_root_mutex);
> > +out:
> > kfree(full_path);
> > return dentry;
> > }
> > @@ -644,16 +682,7 @@ cifs_do_mount(struct file_system_type *fs_type,
> > cifs_umount(cifs_sb);
> > } else {
> > sb->s_flags = flags;
> > - /* BB should we make this contingent on mount parm? */
> > - sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
> > -
> > - rc = cifs_read_super(sb);
> > - if (rc) {
> > - root = ERR_PTR(rc);
> > - goto out_super;
> > - }
> > -
> > - sb->s_flags |= MS_ACTIVE;
> > + cifs_read_super(sb);
> > }
> >
> > root = cifs_get_root(volume_info, sb);
> > @@ -1112,6 +1141,7 @@ init_cifs(void)
> > spin_lock_init(&cifs_tcp_ses_lock);
> > spin_lock_init(&cifs_file_list_lock);
> > spin_lock_init(&GlobalMid_Lock);
> > + mutex_init(&cifs_root_mutex);
> >
> > if (cifs_max_pending < 2) {
> > cifs_max_pending = 2;
> > diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
> > index 30ff560..cf28150 100644
> > --- a/fs/cifs/cifsfs.h
> > +++ b/fs/cifs/cifsfs.h
> > @@ -43,7 +43,8 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf;
> >
> > /* Functions related to inodes */
> > extern const struct inode_operations cifs_dir_inode_ops;
> > -extern struct inode *cifs_root_iget(struct super_block *);
> > +extern struct inode *cifs_mntroot_iget(struct super_block *sb,
> > + const char *full_path);
> > extern int cifs_create(struct inode *, struct dentry *, int,
> > struct nameidata *);
> > extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
> > diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> > index 8238aa1..67f6852 100644
> > --- a/fs/cifs/cifsglob.h
> > +++ b/fs/cifs/cifsglob.h
> > @@ -958,6 +958,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
> > */
> > GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
> >
> > +/*
> > + * This lock protects root dentry in cifs_get_root from being instantiated
> > + * twice.
> > + */
> > +GLOBAL_EXTERN struct mutex cifs_root_mutex;
> > +
> > #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
> > /* Outstanding dir notify requests */
> > GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
> > diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> > index d7eeb9d..d6b3319 100644
> > --- a/fs/cifs/dir.c
> > +++ b/fs/cifs/dir.c
> > @@ -553,6 +553,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> >
> > if (direntry->d_inode != NULL) {
> > cFYI(1, "non-NULL inode in lookup");
> > + newInode = direntry->d_inode;
>
> this and ...
>
> > } else {
> > cFYI(1, "NULL inode in lookup");
> > }
> > @@ -596,7 +597,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> > rc = cifs_get_inode_info(&newInode, full_path, NULL,
> > parent_dir_inode->i_sb, xid, NULL);
> >
> > - if ((rc == 0) && (newInode != NULL)) {
> > + if ((rc == 0) && (newInode != NULL) && !direntry->d_inode) {
>
> ... this doesn't make sense - I made it for testing purpose only and
> forgot to remove. Since this patch isn't going to be a candidate to
> merge, seems no need to respin it.
>
> > d_add(direntry, newInode);
> > if (posix_open) {
> > filp = lookup_instantiate_filp(nd, direntry,
> > diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> > index 2c50bd2..7b7fccd 100644
> > --- a/fs/cifs/inode.c
> > +++ b/fs/cifs/inode.c
> > @@ -878,7 +878,7 @@ retry_iget5_locked:
> > }
> >
> > /* gets root inode */
> > -struct inode *cifs_root_iget(struct super_block *sb)
> > +struct inode *cifs_mntroot_iget(struct super_block *sb, const char *full_path)
> > {
> > int xid;
> > struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> > @@ -888,9 +888,10 @@ struct inode *cifs_root_iget(struct super_block *sb)
> >
> > xid = GetXid();
> > if (tcon->unix_ext)
> > - rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
> > + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
> > else
> > - rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
> > + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid,
> > + NULL);
> >
> > if (!inode) {
> > inode = ERR_PTR(rc);
> > diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
> > index 5de03ec..b2f8851 100644
> > --- a/fs/cifs/readdir.c
> > +++ b/fs/cifs/readdir.c
> > @@ -65,10 +65,8 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
> > }
> > #endif /* DEBUG2 */
> >
> > -/*
> > - * Find the dentry that matches "name". If there isn't one, create one. If it's
> > - * a negative dentry or the uniqueid changed, then drop it and recreate it.
> > - */
> > +
> > +/* Find the dentry that matches "name". If there isn't one, create one. */
> > static struct dentry *
> > cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
> > struct cifs_fattr *fattr)
> > @@ -84,32 +82,38 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
> > else
> > name->hash = full_name_hash(name->name, name->len);
> >
> > + mutex_lock(&cifs_root_mutex);
> > +
> > dentry = d_lookup(parent, name);
> > if (dentry) {
> > /* FIXME: check for inode number changes? */
> > if (dentry->d_inode != NULL)
> > - return dentry;
> > - d_drop(dentry);
> > - dput(dentry);
> > + goto out;
> > + } else {
> > + dentry = d_alloc(parent, name);
> > + if (dentry == NULL)
> > + goto out;
> > + d_rehash(dentry);
> > }
> >
> > - dentry = d_alloc(parent, name);
> > - if (dentry == NULL)
> > - return NULL;
> > -
> > inode = cifs_iget(sb, fattr);
> > if (!inode) {
> > dput(dentry);
> > - return NULL;
> > + dentry = NULL;
> > + goto out;
> > }
> >
> > - alias = d_materialise_unique(dentry, inode);
> > + alias = d_instantiate_unique(dentry, inode);
> > if (alias != NULL) {
> > dput(dentry);
> > - if (IS_ERR(alias))
> > - return NULL;
> > + if (IS_ERR(alias)) {
> > + dentry = NULL;
> > + goto out;
> > + }
> > dentry = alias;
> > }
> > +out:
> > + mutex_unlock(&cifs_root_mutex);
> >
> > return dentry;
> > }
> > @@ -708,6 +712,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
> > char *tmp_buf = NULL;
> > char *end_of_smb;
> > unsigned int max_len;
> > + ino_t ino;
> >
> > xid = GetXid();
> >
> > @@ -732,8 +737,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
> > }
> > file->f_pos++;
> > case 1:
> > - if (filldir(direntry, "..", 2, file->f_pos,
> > - parent_ino(file->f_path.dentry), DT_DIR) < 0) {
> > + if (!file->f_path.dentry->d_parent->d_inode) {
> > + cFYI(1, "parent dir is negative, filling as current");
> > + ino = file->f_path.dentry->d_inode->i_ino;
> > + } else
> > + ino = parent_ino(file->f_path.dentry);
> > + if (filldir(direntry, "..", 2, file->f_pos, ino, DT_DIR) < 0) {
> > cERROR(1, "Filldir for parent dir failed");
> > rc = -ENOMEM;
> > break;
> > --
> > 1.7.1
> >
> >
>
>
>
(cc'ing fsdevel since I think we could use more eyes on this scheme)
I'm not a big fan of this patch. It seems to me that this assumes that
it's ok to have a dentry with a negative dentry as a parent. That makes
no sense though. Anegative dentry is the result of a lookup that
returned the equivalent of -ENOENT. I'm very reticent to play that sort
of game with the dcache code...
What may be better is to do something like this:
Go ahead and instantiate positive dentries from the root of the share
to the root of the vfsmount. However, we would mark those inodes as
"placeholders" and give them a bogus inode number of some sort (maybe
even 0?).
If we end up coming across a dentry with a placeholder d_inode later,
the we'd fetch the inode info and, we could remove and reinsert the
inode into the inode hashtable with the proper inode number.
Another idea might be to keep the root dentry of the mount as a
disconnected root dentry, and then try to graft it into a "parent
mount's" tree later if you end up coming across it from another
vfsmount that contains it. That seems a little trickier to handle
though.
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: cifs and win2k8
2011-11-10 13:24 ` Jeff Layton
@ 2011-11-10 13:38 ` Pavel Shilovsky
0 siblings, 0 replies; 10+ messages in thread
From: Pavel Shilovsky @ 2011-11-10 13:38 UTC (permalink / raw)
To: Jeff Layton; +Cc: linux-cifs, linux-fsdevel
2011/11/10 Jeff Layton <jlayton@samba.org>:
> On Tue, 1 Nov 2011 22:56:18 +0300
> Pavel Shilovsky <piastry@etersoft.ru> wrote:
>
>> 2011/11/1 Pavel Shilovsky <piastry@etersoft.ru>:
>> > Sorry for so long delay on this. Here is the fixed version of the patch:
>> >
>> > [PATCH] CIFS: Fix NT_STATUS_ACCESS_DENIED for mounts with prefixpath option
>> >
>> > but I found out one use case where it doesn't work right:
>> >
>> > 1) mount //server/share/a/b/ test
>> > 2) mount //server/share/ test2
>> > 3) stat test2/a/b - return wrong inode number (autodisable server inode number happens)
>> >
>> > In the same time if I add "ls test2" before step #3 it works! May be VFS can't
>> > handle negative dentry with children in this case, but I am not sure.
>> >
>> > Reorganize code and make it send qpath info request only for a full
>> > path (//server/share/prefixpath) rather than request for every path
>> > compoment. In this case we end up with negative dentries for all
>> > components except full one and we will instantiate them later if
>> > such a mount is requested.
>> >
>> > Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
>> > ---
>> > fs/cifs/cifsfs.c | 138 +++++++++++++++++++++++++++++++--------------------
>> > fs/cifs/cifsfs.h | 3 +-
>> > fs/cifs/cifsglob.h | 6 ++
>> > fs/cifs/dir.c | 3 +-
>> > fs/cifs/inode.c | 7 ++-
>> > fs/cifs/readdir.c | 43 ++++++++++------
>> > 6 files changed, 124 insertions(+), 76 deletions(-)
>> >
>> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
>> > index 8f1fe32..a188be1 100644
>> > --- a/fs/cifs/cifsfs.c
>> > +++ b/fs/cifs/cifsfs.c
>> > @@ -90,14 +90,13 @@ extern mempool_t *cifs_sm_req_poolp;
>> > extern mempool_t *cifs_req_poolp;
>> > extern mempool_t *cifs_mid_poolp;
>> >
>> > -static int
>> > +static void
>> > cifs_read_super(struct super_block *sb)
>> > {
>> > - struct inode *inode;
>> > - struct cifs_sb_info *cifs_sb;
>> > - int rc = 0;
>> > + struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>> >
>> > - cifs_sb = CIFS_SB(sb);
>> > + /* BB should we make this contingent on mount parm? */
>> > + sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
>> >
>> > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
>> > sb->s_flags |= MS_POSIXACL;
>> > @@ -115,26 +114,6 @@ cifs_read_super(struct super_block *sb)
>> > sb->s_bdi = &cifs_sb->bdi;
>> > sb->s_blocksize = CIFS_MAX_MSGSIZE;
>> > sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
>> > - inode = cifs_root_iget(sb);
>> > -
>> > - if (IS_ERR(inode)) {
>> > - rc = PTR_ERR(inode);
>> > - inode = NULL;
>> > - goto out_no_root;
>> > - }
>> > -
>> > - sb->s_root = d_alloc_root(inode);
>> > -
>> > - if (!sb->s_root) {
>> > - rc = -ENOMEM;
>> > - goto out_no_root;
>> > - }
>> > -
>> > - /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
>> > - if (cifs_sb_master_tcon(cifs_sb)->nocase)
>> > - sb->s_d_op = &cifs_ci_dentry_ops;
>> > - else
>> > - sb->s_d_op = &cifs_dentry_ops;
>> >
>> > #ifdef CONFIG_CIFS_NFSD_EXPORT
>> > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
>> > @@ -143,14 +122,7 @@ cifs_read_super(struct super_block *sb)
>> > }
>> > #endif /* CONFIG_CIFS_NFSD_EXPORT */
>> >
>> > - return 0;
>> > -
>> > -out_no_root:
>> > - cERROR(1, "cifs_read_super: get root inode failed");
>> > - if (inode)
>> > - iput(inode);
>> > -
>> > - return rc;
>> > + sb->s_flags |= MS_ACTIVE;
>> > }
>> >
>> > static void cifs_kill_sb(struct super_block *sb)
>> > @@ -528,6 +500,17 @@ static const struct super_operations cifs_super_ops = {
>> > #endif
>> > };
>> >
>> > +static struct dentry *
>> > +cifs_alloc_root(struct super_block *sb)
>> > +{
>> > + struct qstr q;
>> > +
>> > + q.name = "/";
>> > + q.len = 1;
>> > + q.hash = full_name_hash(q.name, q.len);
>> > + return d_alloc_pseudo(sb, &q);
>> > +}
>> > +
>> > /*
>> > * Get root dentry from superblock according to prefix path mount option.
>> > * Return dentry with refcount + 1 on success and NULL otherwise.
>> > @@ -535,8 +518,10 @@ static const struct super_operations cifs_super_ops = {
>> > static struct dentry *
>> > cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>> > {
>> > - struct dentry *dentry;
>> > + struct dentry *dentry, *found;
>> > + struct inode *inode;
>> > struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>> > + struct qstr q;
>> > char *full_path = NULL;
>> > char *s, *p;
>> > char sep;
>> > @@ -548,20 +533,30 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>> >
>> > cFYI(1, "Get root dentry for %s", full_path);
>> >
>> > + if (!sb->s_root) {
>> > + sb->s_root = cifs_alloc_root(sb);
>> > + if (IS_ERR(sb->s_root)) {
>> > + dentry = ERR_PTR(-ENOMEM);
>> > + goto out;
>> > + }
>> > +
>> > + /*
>> > + * do that *after* cifs_alloc_root() - we want NULL ->d_op for
>> > + * root here
>> > + */
>> > + if (cifs_sb_master_tcon(cifs_sb)->nocase)
>> > + sb->s_d_op = &cifs_ci_dentry_ops;
>> > + else
>> > + sb->s_d_op = &cifs_dentry_ops;
>> > + }
>> > +
>> > sep = CIFS_DIR_SEP(cifs_sb);
>> > dentry = dget(sb->s_root);
>> > p = s = full_path;
>> >
>> > do {
>> > - struct inode *dir = dentry->d_inode;
>> > struct dentry *child;
>> >
>> > - if (!dir) {
>> > - dput(dentry);
>> > - dentry = ERR_PTR(-ENOENT);
>> > - break;
>> > - }
>> > -
>> > /* skip separators */
>> > while (*s == sep)
>> > s++;
>> > @@ -572,12 +567,55 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>> > while (*s && *s != sep)
>> > s++;
>> >
>> > - mutex_lock(&dir->i_mutex);
>> > - child = lookup_one_len(p, dentry, s - p);
>> > - mutex_unlock(&dir->i_mutex);
>> > + q.name = p;
>> > + q.len = s - p;
>> > + if (dentry->d_flags & DCACHE_OP_HASH)
>> > + dentry->d_op->d_hash(dentry, dentry->d_inode, &q);
>> > + else
>> > + q.hash = full_name_hash(q.name, q.len);
>> > +
>> > + child = d_lookup(dentry, &q);
>> > + if (!child) {
>> > + child = d_alloc(dentry, &q);
>> > + if (IS_ERR(child)) {
>> > + dput(dentry);
>> > + dentry = ERR_CAST(child);
>> > + break;
>> > + }
>> > + d_rehash(child);
>> > + }
>> > dput(dentry);
>> > dentry = child;
>> > } while (!IS_ERR(dentry));
>> > +
>> > + if (IS_ERR(dentry))
>> > + goto out;
>> > +
>> > + mutex_lock(&cifs_root_mutex);
>> > +
>> > + if (dentry->d_parent->d_inode)
>> > + mutex_lock(&dentry->d_parent->d_inode->i_mutex);
>> > +
>> > + if (!dentry->d_inode) {
>> > + inode = cifs_mntroot_iget(sb, full_path);
>> > + if (IS_ERR(inode)) {
>> > + dput(dentry);
>> > + dentry = ERR_CAST(inode);
>> > + goto out;
>> > + }
>> > +
>> > + found = d_instantiate_unique(dentry, inode);
>> > + if (found) {
>> > + dput(dentry);
>> > + dentry = found;
>> > + }
>> > + }
>> > +
>> > + if (dentry->d_parent->d_inode)
>> > + mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
>> > +
>> > + mutex_unlock(&cifs_root_mutex);
>> > +out:
>> > kfree(full_path);
>> > return dentry;
>> > }
>> > @@ -644,16 +682,7 @@ cifs_do_mount(struct file_system_type *fs_type,
>> > cifs_umount(cifs_sb);
>> > } else {
>> > sb->s_flags = flags;
>> > - /* BB should we make this contingent on mount parm? */
>> > - sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
>> > -
>> > - rc = cifs_read_super(sb);
>> > - if (rc) {
>> > - root = ERR_PTR(rc);
>> > - goto out_super;
>> > - }
>> > -
>> > - sb->s_flags |= MS_ACTIVE;
>> > + cifs_read_super(sb);
>> > }
>> >
>> > root = cifs_get_root(volume_info, sb);
>> > @@ -1112,6 +1141,7 @@ init_cifs(void)
>> > spin_lock_init(&cifs_tcp_ses_lock);
>> > spin_lock_init(&cifs_file_list_lock);
>> > spin_lock_init(&GlobalMid_Lock);
>> > + mutex_init(&cifs_root_mutex);
>> >
>> > if (cifs_max_pending < 2) {
>> > cifs_max_pending = 2;
>> > diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
>> > index 30ff560..cf28150 100644
>> > --- a/fs/cifs/cifsfs.h
>> > +++ b/fs/cifs/cifsfs.h
>> > @@ -43,7 +43,8 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf;
>> >
>> > /* Functions related to inodes */
>> > extern const struct inode_operations cifs_dir_inode_ops;
>> > -extern struct inode *cifs_root_iget(struct super_block *);
>> > +extern struct inode *cifs_mntroot_iget(struct super_block *sb,
>> > + const char *full_path);
>> > extern int cifs_create(struct inode *, struct dentry *, int,
>> > struct nameidata *);
>> > extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
>> > diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
>> > index 8238aa1..67f6852 100644
>> > --- a/fs/cifs/cifsglob.h
>> > +++ b/fs/cifs/cifsglob.h
>> > @@ -958,6 +958,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
>> > */
>> > GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
>> >
>> > +/*
>> > + * This lock protects root dentry in cifs_get_root from being instantiated
>> > + * twice.
>> > + */
>> > +GLOBAL_EXTERN struct mutex cifs_root_mutex;
>> > +
>> > #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
>> > /* Outstanding dir notify requests */
>> > GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
>> > diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
>> > index d7eeb9d..d6b3319 100644
>> > --- a/fs/cifs/dir.c
>> > +++ b/fs/cifs/dir.c
>> > @@ -553,6 +553,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
>> >
>> > if (direntry->d_inode != NULL) {
>> > cFYI(1, "non-NULL inode in lookup");
>> > + newInode = direntry->d_inode;
>>
>> this and ...
>>
>> > } else {
>> > cFYI(1, "NULL inode in lookup");
>> > }
>> > @@ -596,7 +597,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
>> > rc = cifs_get_inode_info(&newInode, full_path, NULL,
>> > parent_dir_inode->i_sb, xid, NULL);
>> >
>> > - if ((rc == 0) && (newInode != NULL)) {
>> > + if ((rc == 0) && (newInode != NULL) && !direntry->d_inode) {
>>
>> ... this doesn't make sense - I made it for testing purpose only and
>> forgot to remove. Since this patch isn't going to be a candidate to
>> merge, seems no need to respin it.
>>
>> > d_add(direntry, newInode);
>> > if (posix_open) {
>> > filp = lookup_instantiate_filp(nd, direntry,
>> > diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>> > index 2c50bd2..7b7fccd 100644
>> > --- a/fs/cifs/inode.c
>> > +++ b/fs/cifs/inode.c
>> > @@ -878,7 +878,7 @@ retry_iget5_locked:
>> > }
>> >
>> > /* gets root inode */
>> > -struct inode *cifs_root_iget(struct super_block *sb)
>> > +struct inode *cifs_mntroot_iget(struct super_block *sb, const char *full_path)
>> > {
>> > int xid;
>> > struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>> > @@ -888,9 +888,10 @@ struct inode *cifs_root_iget(struct super_block *sb)
>> >
>> > xid = GetXid();
>> > if (tcon->unix_ext)
>> > - rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
>> > + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
>> > else
>> > - rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
>> > + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid,
>> > + NULL);
>> >
>> > if (!inode) {
>> > inode = ERR_PTR(rc);
>> > diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
>> > index 5de03ec..b2f8851 100644
>> > --- a/fs/cifs/readdir.c
>> > +++ b/fs/cifs/readdir.c
>> > @@ -65,10 +65,8 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
>> > }
>> > #endif /* DEBUG2 */
>> >
>> > -/*
>> > - * Find the dentry that matches "name". If there isn't one, create one. If it's
>> > - * a negative dentry or the uniqueid changed, then drop it and recreate it.
>> > - */
>> > +
>> > +/* Find the dentry that matches "name". If there isn't one, create one. */
>> > static struct dentry *
>> > cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
>> > struct cifs_fattr *fattr)
>> > @@ -84,32 +82,38 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
>> > else
>> > name->hash = full_name_hash(name->name, name->len);
>> >
>> > + mutex_lock(&cifs_root_mutex);
>> > +
>> > dentry = d_lookup(parent, name);
>> > if (dentry) {
>> > /* FIXME: check for inode number changes? */
>> > if (dentry->d_inode != NULL)
>> > - return dentry;
>> > - d_drop(dentry);
>> > - dput(dentry);
>> > + goto out;
>> > + } else {
>> > + dentry = d_alloc(parent, name);
>> > + if (dentry == NULL)
>> > + goto out;
>> > + d_rehash(dentry);
>> > }
>> >
>> > - dentry = d_alloc(parent, name);
>> > - if (dentry == NULL)
>> > - return NULL;
>> > -
>> > inode = cifs_iget(sb, fattr);
>> > if (!inode) {
>> > dput(dentry);
>> > - return NULL;
>> > + dentry = NULL;
>> > + goto out;
>> > }
>> >
>> > - alias = d_materialise_unique(dentry, inode);
>> > + alias = d_instantiate_unique(dentry, inode);
>> > if (alias != NULL) {
>> > dput(dentry);
>> > - if (IS_ERR(alias))
>> > - return NULL;
>> > + if (IS_ERR(alias)) {
>> > + dentry = NULL;
>> > + goto out;
>> > + }
>> > dentry = alias;
>> > }
>> > +out:
>> > + mutex_unlock(&cifs_root_mutex);
>> >
>> > return dentry;
>> > }
>> > @@ -708,6 +712,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
>> > char *tmp_buf = NULL;
>> > char *end_of_smb;
>> > unsigned int max_len;
>> > + ino_t ino;
>> >
>> > xid = GetXid();
>> >
>> > @@ -732,8 +737,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
>> > }
>> > file->f_pos++;
>> > case 1:
>> > - if (filldir(direntry, "..", 2, file->f_pos,
>> > - parent_ino(file->f_path.dentry), DT_DIR) < 0) {
>> > + if (!file->f_path.dentry->d_parent->d_inode) {
>> > + cFYI(1, "parent dir is negative, filling as current");
>> > + ino = file->f_path.dentry->d_inode->i_ino;
>> > + } else
>> > + ino = parent_ino(file->f_path.dentry);
>> > + if (filldir(direntry, "..", 2, file->f_pos, ino, DT_DIR) < 0) {
>> > cERROR(1, "Filldir for parent dir failed");
>> > rc = -ENOMEM;
>> > break;
>> > --
>> > 1.7.1
>> >
>> >
>>
>>
>>
>
> (cc'ing fsdevel since I think we could use more eyes on this scheme)
>
> I'm not a big fan of this patch. It seems to me that this assumes that
> it's ok to have a dentry with a negative dentry as a parent. That makes
> no sense though. Anegative dentry is the result of a lookup that
> returned the equivalent of -ENOENT. I'm very reticent to play that sort
> of game with the dcache code...
>
Jeff, now I agree with you that keeping negative dentries with
childrens is not a good idea. That really breaks some VFS assumptions.
> What may be better is to do something like this:
>
> Go ahead and instantiate positive dentries from the root of the share
> to the root of the vfsmount. However, we would mark those inodes as
> "placeholders" and give them a bogus inode number of some sort (maybe
> even 0?).
>
Yes, I was thinking about this approach too but didn't have enough
time to prototype it. It seems easier to implement than the second one
but now I don't imagine what problems we can faced with going this
way.
--
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-11-10 13:38 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-21 11:18 cifs and win2k8 Terrence Shipclark
[not found] ` <4EA154FC.3090601-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2011-10-21 11:20 ` Terrence Shipclark
2011-10-23 10:30 ` sean finney
[not found] ` <20111023103003.GA6132-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
2011-10-23 10:55 ` Jeff Layton
[not found] ` <20111023065534.566a0aad-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-10-23 19:10 ` Pavel Shilovsky
2011-10-24 7:35 ` sean finney
[not found] ` <20111024073534.GB7086-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>
2011-11-01 18:13 ` Pavel Shilovsky
[not found] ` <1320171185-11150-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org>
2011-11-01 19:56 ` Pavel Shilovsky
[not found] ` <CAKywueRjR+UNg98odoe8x2WmnqdiCtEa_UgwnKt-8AEi0XRFdQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-11-10 13:24 ` Jeff Layton
2011-11-10 13:38 ` Pavel Shilovsky
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.