summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-parser.c
Commit message (Collapse)AuthorAgeFilesLines
* glusterd : Introduce reset brickAnuradha Talur2016-08-291-31/+133
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The command basically allows replace brick with src and dst bricks as same. Usage: gluster v reset-brick <volname> <hostname:brick-path> start This command kills the brick to be reset. Once this command is run, admin can do other manual operations that they need to do, like configuring some options for the brick. Once this is done, resetting the brick can be continued with the following options. gluster v reset-brick <vname> <hostname:brick> <hostname:brick> commit {force} Does the job of resetting the brick. 'force' option should be used when the brick already contains volinfo id. Problem: On doing a disk-replacement of a brick in a replicate volume the following 2 scenarios may occur : a) there is a chance that reads are served from this replaced-disk brick, which leads to empty reads. b) potential data loss if next writes succeed only on replaced brick, and heal is done to other bricks from this one. Solution: After disk-replacement, make sure that reset-brick command is run for that brick so that pending markers are set for the brick and it is not chosen as source for reads and heal. But, as of now replace-brick for the same brick-path is not allowed. In order to fix the above mentioned problem, same brick-path replace-brick is needed. With this patch reset-brick commit {force} will be allowed even when source and destination <hostname:brickpath> are identical as long as 1) destination brick is not alive 2) source and destination brick have the same brick uuid and path. Also, the destination brick after replace-brick will use the same port as the source brick. Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de BUG: 1266876 Signed-off-by: Anuradha Talur <atalur@redhat.com> Reviewed-on: http://review.gluster.org/12250 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Ashish Pandey <aspandey@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
* cli,rpc : Removing logically dead codeMuthu-vigneshwaran2016-08-291-4/+0
| | | | | | | | | | | | | | | CID = 1357865, 1357866 Change-Id: I05eb345e9357d889872d259a600759392b188bb3 BUG: 789278 Signed-off-by: Muthu-vigneshwaran <mvignesh@redhat.com> Reviewed-on: http://review.gluster.org/15148 Tested-by: Muthu Vigneshwaran Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Prashanth Pai <ppai@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Manikandan Selvaganesh <mselvaga@redhat.com>
* cli: fix unused variable warnings/errorsKaleb S. KEITHLEY2016-08-271-12/+0
| | | | | | | | | | | | | | | | | | | http://review.gluster.org/14085 fixes a/the "leak" - via the generated rpc/xdr headers - of pragmas that mask these warnings. However 14085 won't pass the smoke test until all the warnings are fixed. Change-Id: Ifc33762cf62259961ceb35ae9ac3cbec7094b703 BUG: 1369124 Signed-off-by: Kaleb S. KEITHLEY <kkeithle@redhat.com> Reviewed-on: http://review.gluster.org/15238 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: jiffin tony Thottan <jthottan@redhat.com> Reviewed-by: Manikandan Selvaganesh <mselvaga@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* glusterd/cli: cli to get local state representation from glusterdSamikshan Bairagya2016-08-261-0/+114
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently there is no existing CLI that can be used to get the local state representation of the cluster as maintained in glusterd in a readable as well as parseable format. The CLI added has the following usage: # gluster get-state [daemon] [odir <path/to/output/dir>] [file <filename>] This would dump data points that reflect the local state representation of the cluster as maintained in glusterd (no other daemons are supported as of now) to a file inside the specified output directory. The default output directory and filename is /var/run/gluster and glusterd_state_<timestamp> respectively. The option for specifying the daemon name leaves room to add support for other daemons in the future. Following are the data points captured as of now to represent the state from the local glusterd pov: * Peer: - Primary hostname - uuid - state - connection status - List of hostnames * Volumes: - name, id, transport type, status - counts: bricks, snap, subvol, stripe, arbiter, disperse, redundancy - snapd status - quorum status - tiering related information - rebalance status - replace bricks status - snapshots * Bricks: - Path, hostname (for all bricks these info will be shown) - port, rdma port, status, mount options, filesystem type and signed in status for bricks running locally. * Services: - name, online status for initialised services * Others: - Base port, last allocated port - op-version - MYUUID Change-Id: I4a45cc5407ab92d8afdbbd2098ece851f7e3d618 BUG: 1353156 Signed-off-by: Samikshan Bairagya <samikshan@gmail.com> Reviewed-on: http://review.gluster.org/14873 Reviewed-by: Avra Sengupta <asengupt@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
* feature/bitrot: Ondemand scrub option for bitrotKotresh HR2016-08-251-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The bitrot scrubber takes 'hourly/daily/biweekly/monthly' as the values for 'scrub-frequency'. There is no way to schedule the scrubbing when the admin wants it. Ondemand scrubbing brings in the new option 'ondemand' with which the admin can start scrubbing ondemand. It starts the scrubbing immediately. Ondemand scrubbing is successful only if the scrubber is in 'Active (Idle)' (waiting for it's next frequency cycle to start scrubbing). It is not entertained when the scrubber is in 'Paused' or already running. Here is the command line syntax. gluster volume bitrot <vol name> scrub ondemand Change-Id: I84c28904367eed827a7dae8d6a535c14b28e9f4d BUG: 1366195 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/15111 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Venky Shankar <vshankar@redhat.com>
* dict: Don't expose get_new_dict/dict_destroyPranith Kumar K2016-07-251-22/+22
| | | | | | | | | | | | | | | get_new_dict/dict_destroy is causing confusion where, dict_new/dict_destroy or get_new_dict/dict_unref are used instead of dict_new/dict_unref. Change-Id: I4cc69f5b6711d720823395e20fd624a0c6c1168c BUG: 1296043 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/13183 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
* features/bitrot: Option to set scrub interval to a minuteKotresh HR2016-07-051-1/+1
| | | | | | | | | | | | | | | | | | | | Bitrot scrub-frequency supports "hourly|daily|weekly|biweekly|monthly". But it is painful for testing as minimum scrub-interval is an hour Hence introducing a scrub interval of minute to ease testing. It is intentionally not exposed in bitrot command help as it is only for testing. e.g., gluster vol bitrot <volname> scrub-frequency minute Change-Id: I155a65298d3fad5ae9e529d9c7d4b0d25fa297c0 BUG: 1351537 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/14836 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
* georep: add reset-sync-time option for session deleteMilind Changire2016-06-281-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | Set the stime xattr at all the brick roots to (0,0) if the argument reset-sync-time has been provided on the command-line. To avoid testing against directory specific stime, the remote stime is assumed to be minus_infinity, if the root directory stime is set to (0,0), before the directory scan begins. This triggers a full volume resync to slave in the case of a geo-rep session recreation with the same master-slave volume pair. Command synopsis: gluster volume geo-replication <MASTERVOL> <SLAVE>::<SLAVEVOL> delete \ [reset-sync-time] Update gluster cli man page to include new sub-command reset-sync-time. Change-Id: Ie4ce03b9425ed9bb81eda8681058c0fc6f990948 BUG: 1311926 Signed-off-by: Milind Changire <mchangir@redhat.com> Reviewed-on: http://review.gluster.org/14051 Reviewed-by: Kotresh HR <khiremat@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Aravinda VK <avishwan@redhat.com>
* glusterd/cli: coverity fixesAtin Mukherjee2016-06-281-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A downstream coverity run has revealed few of the following coverity defects. Since the downstream code is a clone of a specific upstream branch the defects hold true for the upstream as well. Defect type: NEGATIVE_RETURNS xlators/mgmt/glusterd/src/glusterd-rpc-ops.c:641: negative_returns: "op_errno" is passed to a parameter that cannot be negative. Defect type: BUFFER_SIZE_WARNING xlators/mgmt/glusterd/src/glusterd-volume-ops.c:2124: buffer_size_warning: Calling strncpy with a maximum size argument of 261 bytes on destination array "volinfo->volname" of size 261 bytes might leave the destination string unterminated. Defect type: BUFFER_SIZE_WARNING xlators/mgmt/glusterd/src/glusterd-volgen.c:4888: buffer_size_warning: Calling strncpy with a maximum size argument of 261 bytes on destination array "volinfo->volname" of size 261 bytes might leave the destination string unterminated. Defect type: STRING_OVERFLOW xlators/mgmt/glusterd/src/glusterd-volgen.c:3449: string_overflow: You might overrun the 256 byte destination string "tmp_volname" by writing 261 bytes from "volinfo->volname". Defect type: BUFFER_SIZE_WARNING xlators/mgmt/glusterd/src/glusterd-utils.c:3392: buffer_size_warning: Calling strncpy with a maximum size argument of 261 bytes on destination array "new_volinfo->volname" of size 261 bytes might leave the destination string unterminated. Defect type: NO_EFFECT xlators/mgmt/glusterd/src/glusterd-utils.c:7359: remediation: Was "rebal->rebalance_id" formerly declared as a pointer? Defect type: USE_AFTER_FREE xlators/mgmt/glusterd/src/glusterd-utils.c:7115: pass_freed_arg: Passing freed pointer "volinfo" as an argument to "glusterd_friend_contains_vol_bricks". Defect type: DEADCODE cli/src/cli-cmd-parser.c:1767: dead_error_begin: Execution cannot reach this statement: "ret = -1;". Change-Id: Ie941bdf31923e2f39618dd94bfae16fdb3ad65f1 BUG: 789278 Signed-off-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-on: http://review.gluster.org/14818 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
* cli: fix crash in arbiter keyword parsingRavishankar N2016-06-171-0/+5
| | | | | | | | | | | | | | | | | | | A negative case like `gluster volume create volname arbiter 3 /bricks{1..3}` must not crash. 'arbiter' keyword is valid only for (3 way) replica volumes. The .t that is added will crash and create a core *without* the fix when run but will still pass all TESTs. Since the regression framework fails the .t if it creates a core, we can consider it a valid test 'that fails without the fix'. Change-Id: Ie2d7ced66025ea3617d30f6f823b22401e6d2fde BUG: 1346821 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/14738 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
* cluster/tier: fix detach tier error messageDan Lambright2016-06-131-1/+1
| | | | | | | | | | | | | | | Do not refer to obsolete syntax when throwing an error on detach tier. Throw a warning if the user tries to commit a detach tier before starting (or completing) the decommission process. Change-Id: I9df28c1b42b8ab1790e1db5c0cd518432146c1d1 BUG: 1337227 Signed-off-by: Dan Lambright <dlambrig@redhat.com> Reviewed-on: http://review.gluster.org/14438 Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
* cli/glusterd: add/remove brick fixes for arbiter volumesRavishankar N2016-05-191-0/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1.Provide a command to convert replica 2 volumes to arbiter volumes. Existing self-heal logic will automatically heal the file hierarchy into the arbiter brick, the progress of which can be monitored using the heal info command. Syntax: gluster volume add-brick <VOLNAME> replica 3 arbiter 1 <HOST:arbiter-brick-path> 2. Add checks when removing bricks from arbiter volumes: - When converting from arbiter to replica 2 volume, allow only arbiter brick to be removed. - When converting from arbiter to plain distribute volume, allow only if arbiter is one of the bricks that is removed. 3. Some clean-up: - Use GD_MSG_DICT_GET_SUCCESS instead of GD_MSG_DICT_GET_FAILED to log messages that are not failures. - Remove unused variable `brick_list` - Move 'brickinfo->group' related functions to glusted-utils. Change-Id: Ic87b8c7e4d7d3ab03f93e7b9f372b314d80947ce BUG: 1318289 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/14126 Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
* core: assorted typos and spelling mistakes reported by Debian lintianKaleb S KEITHLEY2016-05-181-1/+1
| | | | | | | | | | | | | | | Also missing bang (!) in #!/bin/bash in shell scripts. Change-Id: I567a4be8f0f31f6285550f243fe802895f6bc43b BUG: 1336793 Reported-by: Patrick Matthäi <pmatthaei@debian.org> Signed-off-by: Kaleb S KEITHLEY <kkeithle@redhat.com> Reviewed-on: http://review.gluster.org/14398 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kotresh HR <khiremat@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
* afr: add mtime based split-brain resolution to CLIRavishankar N2016-03-291-0/+10
| | | | | | | | | | | | | | | | | | | Extended the CLI to include support for split-brain resolution based on mtime. The command syntax is: $:gluster volume heal <VOLNAME> split-brain latest-mtime <FILE> where <FILE> can be either the full file name as seen from the root of the volume (or) the gfid-string representation of the file. Change-Id: I7a16f72ff1a4495aa69f43f22758a9404e958b4f BUG: 1321322 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/13828 Smoke: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
* cli: Do not remove whitespace if key is user.* in volume setAtin Mukherjee2016-03-231-3/+6
| | | | | | | | | | | | | | setting any user.* option can have multiple words in the key and hence skip the process of trimming whitespaces. Change-Id: Ia295428d7cda55e5470fef668325bea497f2333d BUG: 1316499 Signed-off-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-on: http://review.gluster.org/13669 Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Kaushal M <kaushal@redhat.com>
* snapshot/cli: Keep the dict keys uniformAvra Sengupta2016-03-131-1/+1
| | | | | | | | | | | | | | | snapshot info was using a different dictionary key as compared to other snapshot commands. This was throwing a recurring error log in cli.log Change-Id: I9eb9a4541c10a45ec7673a23c89c85a7dce9f3ec BUG: 1316819 Signed-off-by: Avra Sengupta <asengupt@redhat.com> Reviewed-on: http://review.gluster.org/13677 Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
* all: fixes for clang compile warningsKaleb S KEITHLEY2016-02-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | cli/src/cli-cmd-parser.c (chenk) cli/src/cli-xml-output.c (spandit) cli/src/cli.c (chenk) libglusterfs/src/common-utils.c (vmallika) libglusterfs/src/gfdb/gfdb_sqlite3.c (jfernand +1) rpc/rpc-transport/socket/src/socket.c (?) xlators/cluster/afr/src/afr-transaction.c (?) xlators/cluster/dht/src/dht-common.h (srangana +2) xlators/cluster/dht/src/dht-selfheal.c (srangana +2) xlators/debug/io-stats/src/io-stats.c (R. Wareing) xlators/features/barrier/src/barrier.c (vshastry) xlators/features/bit-rot/src/bitd/bit-rot-scrub.h (vshankar +1) xlators/features/shard/src/shard.c (kdhananj +1) xlators/mgmt/glusterd/src/glusterd-ganesha.c (skoduri) xlators/mgmt/glusterd/src/glusterd-handler.c (atinmu) xlators/mgmt/glusterd/src/glusterd-op-sm.h (atinmu) xlators/mgmt/glusterd/src/glusterd-snapshot.c (spandit) xlators/mgmt/glusterd/src/glusterd-syncop.c (atinmu) xlators/mgmt/glusterd/src/glusterd-volgen.c (atinmu) xlators/protocol/client/src/client-messages.h (mselvaga +1) xlators/storage/bd/src/bd-helper.c (M. Mohan Kumar) xlators/storage/bd/src/bd.c (M. Mohan Kumar) xlators/storage/posix/src/posix.c (nbalacha +1) Change-Id: I85934fbcaf485932136ef3acd206f6ebecde61dd BUG: 1293133 Signed-off-by: Kaleb S KEITHLEY <kkeithle@redhat.com> Reviewed-on: http://review.gluster.org/13031 CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
* cli/quota : quota is not enforcing when limit is set to 0Manikandan Selvaganesh2016-02-101-7/+9
| | | | | | | | | | | | | | | | When limit value is set to 0, quota assumes that limit is not set and is not enforcing currently. The patch fixes this issue by restricting the user from setting limit value = 0. Change-Id: I316653165cd9766600f95b5f23e5b8abcc2b41e7 BUG: 1302554 Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com> Reviewed-on: http://review.gluster.org/13309 Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Kaushal M <kaushal@redhat.com>
* Tier: "tier start force" command implementationhari gowtham2015-12-221-8/+25
| | | | | | | | | | | | | | | | The start command doesnt restart the tier deamon if the deamon is running at one node. hence to bring up the tierd on the nodes where the deamon is down, the force command is implemented. It skips the check for tierd running. Change-Id: I0037d3e5ecfe56637d0da201a97903c435d26436 BUG: 1292112 Signed-off-by: hari gowtham <hgowtham@redhat.com> Reviewed-on: http://review.gluster.org/12983 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com> Tested-by: Dan Lambright <dlambrig@redhat.com>
* glusterd/bitrot : Integration of bad files from bitd with scrub status commandGaurav Kumar Garg2015-11-231-18/+5
| | | | | | | | | | | | | | | | Currently scrub status command is not displaying list of all the bad files. All the bad files are avaliable in the bitd daemon. With this patch it will dispaly list of all the bad file's in the scrub status command. Change-Id: If09babafaf5d7cf158fa79119abbf5b986027748 BUG: 1207627 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/12720 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
* glusterd: cli command implementation for bitrot scrub statusGaurav Kumar Garg2015-11-191-1/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CLI command for bitrot scrub status will be : gluster volume bitrot <volname> scrub status Above command will show the statistics of bitrot scrubber. Upon execution of this command it will show some common scrubber tunable value of volume <VOLNAME> followed by statistics of scrubber statistics of individual nodes. sample ouput for single node: Volume name : <VOLNAME> State of scrub: Active Scrub frequency: biweekly Bitrot error log location: /var/log/glusterfs/bitd.log Scrubber error log location: /var/log/glusterfs/scrub.log ========================================================= Node name: Number of Scrubbed files: Number of Unsigned files: Last completed scrub time: Duration of last scrub: Error count: ========================================================= This is just infrastructure. list of bad file, last scrub time, error count value will be taken care by http://review.gluster.org/#/c/12503/ and http://review.gluster.org/#/c/12654/ patches. Change-Id: I3ed3c7057c9d0c894233f4079a7f185d90c202d1 BUG: 1207627 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/10231 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com>
* glusterd/geo-rep: Adding ssh-port option for geo-rep createKotresh HR2015-11-181-30/+57
| | | | | | | | | | | | | | | | | | | Geo-replication uses default ssh port 22 for setup. i.e., to distribute ssh keys to slaves. In container environments, custom port number might be used. Hence to support custom port number for ssh, option is provided in geo-rep create command to take the same. Change-Id: I0fb61959b1c085342b8e4c21ac4e076fba5462f1 BUG: 1276028 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/12504 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Avra Sengupta <asengupt@redhat.com> Reviewed-by: Aravinda VK <avishwan@redhat.com> Reviewed-by: Venky Shankar <vshankar@redhat.com>
* tier/cli : throw a warning when user issues a detach-tier commit/forceManikandan Selvaganesh2015-10-051-1/+3
| | | | | | | | | | | | | command Change-Id: Idf7664d509156ce46ef4308ffc07fb556a0aedd2 BUG: 1268755 Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com> Reviewed-on: http://review.gluster.org/12297 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: mohammed rafi kc <rkavunga@redhat.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com>
* Tier/cli: Change detach-tier commit force to detach-tier forceMohammed Rafi KC2015-09-221-15/+4
| | | | | | | | | | | | | | | | | | Current detach-tier cli command support commit force. Deprecating the same to force. So the new syntax would be: volume detach-tier <VOLNAME> <start|stop|status|commit|force> Change-Id: Ie86dfd72341078c0a1be94767f523730911312ef BUG: 1261862 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/12151 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com> Tested-by: Dan Lambright <dlambrig@redhat.com>
* cluster/tier: add gluster v tier <vol>Dan Lambright2015-09-091-0/+68
| | | | | | | | | | | | | | | | | | | | | | | Currently the tier feature piggy backs off the rebalance command syntax to obtain status and this is clumsy. Introduce a new tier command that can do tier specific operations, starting with volume status to display counters. Old commands: gluster volume attach-tier <vol> [replica count] {bricklist..} gluster volume detach-tier <vol> {start|stop|commit} New commands: gluster volume tier <vol> attach [replica count] {bricklist} | detach {start|stop|commit} | status Change-Id: Ic07b3c6260588162de7d34380f8cbd3d8a7f35d3 BUG: 1255693 Signed-off-by: Dan Lambright <dlambrig@redhat.com> Reviewed-on: http://review.gluster.org/11984 Reviewed-by: Gaurav Kumar Garg <ggarg@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
* all: reduce "inline" usageJeff Darcy2015-09-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | There are three kinds of inline functions: plain inline, extern inline, and static inline. All three have been removed from .c files, except those in "contrib" which aren't our problem. Inlines in .h files, which are overwhelmingly "static inline" already, have generally been left alone. Over time we should be able to "lower" these into .c files, but that has to be done in a case-by-case fashion requiring more manual effort. This part was easy to do automatically without (as far as I can tell) any ill effect. In the process, several pieces of dead code were flagged by the compiler, and were removed. Change-Id: I56a5e614735c9e0a6ee420dab949eac22e25c155 BUG: 1245331 Signed-off-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-on: http://review.gluster.org/11769 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Dan Lambright <dlambrig@redhat.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Niels de Vos <ndevos@redhat.com> Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-by: Venky Shankar <vshankar@redhat.com>
* gluster/cli: snapshot delete all does not work with xmlRajesh Joseph2015-08-281-2/+2
| | | | | | | | | | | | | Problem: snapshot delete all command fails with --xml option Fix: Provided xml support for delete all command Change-Id: I77cad131473a9160e188c783f442b6a38a37f758 BUG: 1257533 Signed-off-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-on: http://review.gluster.org/12027 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Avra Sengupta <asengupt@redhat.com>
* quota : checking for absolute path in quota commandManikandan Selvaganesh2015-08-121-0/+6
| | | | | | | | | | | | | | | | | | Currently, if absolute path is not entered in "gluster volume quota <vol-name> list <path>", it just shows the header (Path Hard-limit Soft-limit...) instead of showing an error message. With this patch, it shows an error to enter the absolute path. Change-Id: I2c3d34bfdc7b924d00b11f8649b73a5069cbc2dc BUG: 1245558 Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com> Reviewed-on: http://review.gluster.org/11738 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
* quota : validating soft limit percentage.Manikandan Selvaganesh2015-07-201-2/+4
| | | | | | | | | | | Change-Id: I14c049c84c468b6415a1de45441b2fed94e8ed4b BUG: 1240654 Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com> Reviewed-on: http://review.gluster.org/11566 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
* glusterd: Fix snapshot of a volume with geo-repKotresh HR2015-06-171-2/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Snapshot fails for a volume configured with geo-rep if geo-rep is created with root user with the following syntax. gluster vol geo-rep <master_vol> root@<slave_host>::<slave_vol> It works fine if created with following syntax. gluster vol geo-rep <master_vol> <slave_host>::<slave_vol> Cause: Geo-rep maintains persistent dictionary of slave associated with master volume. The dictionary saves the slave info along with 'root@' as sent from cli. Snapshot while constructing the working dir path to copy configuration files, constructs using this dictionary. But the actual working dir is created with out considering 'root@'. Hence the issue. Fix: Fix is done at two layers. 1. Parse and negelect 'root@' in cli itself. 2. For existing geo-rep sessions and upgrade scenarios, parse and neglect 'root@' in snapshot code as well. Change-Id: If4e04f7f776ef71df4dd1e7e053ef75db98762b2 BUG: 1231789 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/11233 Reviewed-by: Avra Sengupta <asengupt@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
* NFS-Ganesha: Automatically export vol that was exported before vol restartMeghana M2015-06-161-1/+2
| | | | | | | | | | | | | | | | | | | | Consider a volume that is exported via NFS-Ganesha. Stopping this volume will automatically unexport the volume. Starting this volume should automatically export it. Although the logic was already there, there was a bug in it. Fixing the same by introducing a hook script. Also with the new CLI options, the hook script S31ganesha-set.sh is no longer required. Hence, removing the same. Adding a comment to tell the user that one of the CLI commands will take a few minutes to complete. Change-Id: Ibff769ca04fef0c2a129c83fe31fc9c869350e8d BUG: 1231738 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Reviewed-on: http://review.gluster.org/11247 Reviewed-by: soumya k <skoduri@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
* features/bitrot: tuanble object signing waiting time value for bitrotGaurav Kumar Garg2015-06-151-3/+31
| | | | | | | | | | | | | | Currently bitrot using 120 second waiting time for object to be signed after all fop's released. This signing waiting time value should be tunable. Command for changing the signing waiting time will be #gluster volume bitrot <VOLNAME> signing-time <waiting time value in second> Change-Id: I89f3121564c1bbd0825f60aae6147413a2fbd798 BUG: 1228680 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Signed-off-by: Venky Shankar <vshankar@redhat.com> Reviewed-on: http://review.gluster.org/11105
* glusterd/shared_storage: Provide a volume set option to create and mount the ↵Avra Sengupta2015-06-041-10/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | shared storage Introducing a global volume set option(cluster.enable-shared-storage) which helps create and set-up the shared storage meta volume. gluster volume set all cluster.enable-shared-storage enable On enabling this option, the system analyzes the number of peers in the cluster, which are currently connected, and chooses three such peers(including the node the command is issued from). From these peers a volume(gluster_shared_storage) is created. Depending on the number of peers available the volume is either a replica 3 volume(if there are 3 connected peers), or a replica 2 volume(if there are 2 connected peers). "/var/run/gluster/ss_brick" serves as the brick path on each node for the shared storage volume. We also mount the shared storage at "/var/run/gluster/shared_storage" on all the nodes in the cluster as part of enabling this option. If there is only one node in the cluster, or only one node is up then the command will fail Once the volume is created, and mounted the maintainance of the volume like adding-bricks, removing bricks etc., is expected to be the onus of the user. On disabling the option, we provide the user a warning, and on affirmation from the user we stop the shared storage volume, and unmount it from all the nodes in the cluster. gluster volume set all cluster.enable-shared-storage disable Change-Id: Idd92d67b93f444244f99ede9f634ef18d2945dbc BUG: 1222013 Signed-off-by: Avra Sengupta <asengupt@redhat.com> Reviewed-on: http://review.gluster.org/10793 Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
* cli: Fix incorrect parse logic for volume heal commandsAnuradha2015-06-021-2/+2
| | | | | | | | | | | | | | heal-op was being incorrectly set to GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE. Change-Id: I4d4461c7737feae30102e82f7788083017485669 BUG: 1221128 Signed-off-by: Anuradha <atalur@redhat.com> Reviewed-on: http://review.gluster.org/10771 Reviewed-by: Ravishankar N <ravishankar@redhat.com> Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
* build: do not #include "config.h" in each fileNiels de Vos2015-05-291-5/+0
| | | | | | | | | | | | | | | | | | Instead of including config.h in each file, and have the additional config.h included from the compiler commandline (-include option). When a .c file tests for a certain #define, and config.h was not included, incorrect assumtions were made. With this change, it can not happen again. BUG: 1222319 Change-Id: I4f9097b8740b81ecfe8b218d52ca50361f74cb64 Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/10808 Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
* features/bitrot: reimplement scrubbing frequencyVenky Shankar2015-05-281-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch reimplments existing scrub-frequency mechanism used to schedule scrubber runs. Existing mechanism uses periodic sleeps (waking up periodically on minimum granularity) and performing a number of tracking checks based on counters and sleep times. This patch does away with all the nifty counters and uses timer-wheel to schedule scrub runs. Scheduling changes are peformed by merely calculating the new expiry time and calling mod_timer() [mod_timer_pending() in some cases] making the code more debuggable and easier to follow. This also introduces "hourly" scrubbing tunable as an aid for testing scrubbing during development/testing cycle. One could also implement on-demand scrubbing with ease: by invoking mod_timer() with an expiry of one (1) second, thereby scheduling a scrub run the very next second. Change-Id: I6c7c5f0c6c9f886bf574d88c04cde14b76e60a8b BUG: 1224596 Signed-off-by: Venky Shankar <vshankar@redhat.com> Reviewed-on: http://review.gluster.org/10893 Reviewed-by: Gaurav Kumar Garg <ggarg@redhat.com> Tested-by: NetBSD Build System Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* cli/tiering: Enhance cli output for tieringMohammed Rafi KC2015-05-081-1/+1
| | | | | | | | | | | | | | Fix for handling cli output for attach-tier and detach-tier Change-Id: I4d17f4b09612754fe1b8cec6c2e14927029b9678 BUG: 1211562 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/10284 Reviewed-by: Dan Lambright <dlambrig@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* tiering: Do not allow some operations on tiered volumeMohammed Rafi KC2015-05-071-1/+1
| | | | | | | | | | | | | | | | | Some operations like add-brick,remove-brick,rebalance, replace-brick are not supported on tiered volume. But there is no code level check for this. This patch will allow to do the same Change-Id: I12689f4e902cf0cceaf6f7f29c71057305024977 BUG: 1205624 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/10349 Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
* glusterd: remove replace brick with data migration support form cli/glusterdGaurav Kumar Garg2015-05-071-81/+19
| | | | | | | | | | | | | | | | Replace-brick operation with data migration support have been deprecated from gluster. With this fix replace brick command will support only one commad gluster volume replace-brick <VOLNAME> <SOURCE-BRICK> <NEW-BRICK> {commit force} Change-Id: Ib81d49e5d8e7eaa4ccb5830cfec2bc081191b43b BUG: 1094119 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/10101 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaushal M <kaushal@redhat.com>
* quota/marker: turn off inode quotas by defaultvmallika2015-05-061-0/+54
| | | | | | | | | | | | | | | | | | | | | inode quota is a new feature implemented in glusterfs-3.7 if quota is enabled in the older version and is upgraded to a new version, we can hit setxattr spike during self-heal of inode quotas. So, when a quota is enabled, turn off inode-quotas with a xlator option. With this patch, we still account for inode quotas but only when a write operation is performed for a particular file. User will be able to query inode quotas once the Inode-quota xlator option is enabled. Change-Id: I52fb28bf7024989ce7bb08ac63a303bf3ec1ec9a BUG: 1209430 Signed-off-by: vmallika <vmallika@redhat.com> Signed-off-by: Sachin Pandit <spandit@redhat.com> Reviewed-on: http://review.gluster.org/10152 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* NFS-Ganesha : Locking global options fileMeghana Madhusudhan2015-05-061-0/+25
| | | | | | | | | | | | | | | | | | | | | Global option gluster features.ganesha enable writes into the global 'option' file. The snapshot feature also writes into the same file. To handle concurrent multiple transactions correctly, a new lock has to be introduced on this file. Every operation using this file needs to contest for the new lock type. Change-Id: Ia8a324d2a466717b39f2700599edd9f345b939a9 BUG: 1200254 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Reviewed-on: http://review.gluster.org/10130 Reviewed-by: Avra Sengupta <asengupt@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: soumya k <skoduri@redhat.com> Tested-by: NetBSD Build System Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
* geo-rep: Status EnhancementsAravinda VK2015-05-051-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Discussion in gluster-devel http://www.gluster.org/pipermail/gluster-devel/2015-April/044301.html MASTER NODE - Master Volume Node MASTER VOL - Master Volume name MASTER BRICK - Master Volume Brick SLAVE USER - Slave User to which Geo-rep session is established SLAVE - <SLAVE_NODE>::<SLAVE_VOL> used in Geo-rep Create command SLAVE NODE - Slave Node to which Master worker is connected STATUS - Worker Status(Created, Initializing, Active, Passive, Faulty, Paused, Stopped) CRAWL STATUS - Crawl type(Hybrid Crawl, History Crawl, Changelog Crawl) LAST_SYNCED - Last Synced Time(Local Time in CLI output and UTC in XML output) ENTRY - Number of entry Operations pending.(Resets on worker restart) DATA - Number of Data operations pending(Resets on worker restart) META - Number of Meta operations pending(Resets on worker restart) FAILURES - Number of Failures CHECKPOINT TIME - Checkpoint set Time(Local Time in CLI output and UTC in XML output) CHECKPOINT COMPLETED - Yes/No or N/A CHECKPOINT COMPLETION TIME - Checkpoint Completed Time(Local Time in CLI output and UTC in XML output) XML output: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> cliOutput> geoRep> volume> name> sessions> session> session_slave> pair> master_node> master_brick> slave_user> slave/> slave_node> status> crawl_status> entry> data> meta> failures> checkpoint_completed> master_node_uuid> last_synced> checkpoint_time> checkpoint_completion_time> BUG: 1212410 Change-Id: I944a6c3c67f1e6d6baf9670b474233bec8f61ea3 Signed-off-by: Aravinda VK <avishwan@redhat.com> Reviewed-on: http://review.gluster.org/10121 Tested-by: NetBSD Build System Reviewed-by: Kotresh HR <khiremat@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* quota: support for inode quota in quota.confvmallika2015-05-041-1/+2
| | | | | | | | | | | | | | | | | Currently when quota limit is set, corresponding gfid is set in quota.conf. This patch supports storing inode-quota limits in quota.conf and also stores additional byte for each gfid to differentiate between usage quota limit and inode quota limit. Change-Id: I444d7399407594edd280e640681679a784d4c46a BUG: 1202244 Signed-off-by: vmallika <vmallika@redhat.com> Signed-off-by: Sachin Pandit <spandit@redhat.com> Reviewed-on: http://review.gluster.org/10069 Tested-by: NetBSD Build System Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
* glusterd: gluster volume status should show status of bitrot and scrubber daemonGaurav Kumar Garg2015-05-041-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | Command gluster volume status <VOLNAME> should show the status of bitrot and scrubber daemon and its pid information. Along with displaying bitrot and scrubber daemon information in gluster volume status command there should be command to show its individual status separately. Command to show individual status of bitrot and scrubber daemon will following. command to show only bitd daemon information will be gluster volume status <VOLNAME> bitd command to show only scrubber daemon information gluster volume status <VOLNAME> scrub Change-Id: Id86aae1156c8c599347c98e2a538f294d37376e4 BUG: 1209752 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/10175 Reviewed-by: Kaushal M <kaushal@redhat.com> Tested-by: Kaushal M <kaushal@redhat.com>
* cli/tiering : Parse detach-tier command properlyMohammed Rafi KC2015-04-301-3/+13
| | | | | | | | | | | | | | | | | gluster detach-tier help should show the usage of detach-tier command properly. Also, instead of force option, if any other was given, then the command should fail with a usage message Change-Id: Ie801529176db067c98fd1bfada056cbc647973fb BUG: 1211570 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/10303 Tested-by: NetBSD Build System Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com>
* NFS-Ganesha: Handling CLI commands when NFS-Ganesha keys are setMeghana Madhusudhan2015-04-301-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When ganesha.enable is set to on and features.ganesha is enabled, there are a few behaviour changes that should be seen in other volume operations. 1. ganesha.enable can be set to 'on' only when features.ganesha is set to 'enable' 2.When gluster vol is started, and if ganesha.enable key was set to 'on', it should automatically export the volume via NFS-Ganesha. 3.When ganesha.enable is set to 'on', and a volume is stopped, that volume should be unexported via NFS-Ganesha. 4. gluster vol reset <volname> If ganesha.enable was set to on, then unexport the volume via NFS-Ganesha. 5. gluster vol reset all If features.ganesha is set to enable, as part of reset all, set it to disable. This translates to teardown cluster. All the above problems are fixed by checking the global key and value, depending on the value, specific functions are called. And also, functions related to global commands are moved to cli-cmd-global.c Commit phase of features.ganesha enable/disable runs the ganesha-ha.sh setup/teardown respectively. Before the script begins, it is important that the NFS-Ganesha service starts on all the HA nodes. Having the start service commands in the commit phase could lead to problems. Moving the pre-requisite service start commands to the 'stage' phase. Change-Id: I5a256f94f8e1310ddcd5369f329b7168b2a24c47 BUG: 1200265 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Reviewed-on: http://review.gluster.org/10283 Reviewed-by: jiffin tony Thottan <jthottan@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
* cli,doc: man page of gluster (man gluster) should show bitrot command ↵Gaurav Kumar Garg2015-04-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | information Currently when user type incorrent bitrot specific command then every time cli error suggest wrong command to reuse. With this fix it cli will suggest specific bitrot command when user type wrong bitrot command. With this fix it will also display bitrot command information in man page by typing 'man gluster' Change-Id: I7dbf31332a8cc0723e54e8a37fea0afe19d95e0e BUG: 1207532 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/10273 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Venky Shankar <vshankar@redhat.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: NetBSD Build System Reviewed-by: Kaushal M <kaushal@redhat.com>
* cli: fix vol_type in volume info xmlAtin Mukherjee2015-04-261-0/+9
| | | | | | | | | | | | xml parsing of voltype should be inline with the cli Change-Id: I41ddddac00d07f03b56a041e1c3f5a132fbd7393 BUG: 1212398 Signed-off-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-on: http://review.gluster.org/10271 Tested-by: NetBSD Build System Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaushal M <kaushal@redhat.com>
* cli: validate brick while creating replicate volumeGaurav Kumar Garg2015-04-231-17/+21
| | | | | | | | | | | | | | | | | | | When user create replicate volume by typing incomplete command "gluster volume create <VOLNAME> replica replica_count" then cli is crashing. Fix is to validate command properly. If user have not given any brick then it should return proper cli command usage error message. Change-Id: I3d4096a144e20f21ab956049af1dae196217a807 BUG: 1211576 Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com> Reviewed-on: http://review.gluster.org/10245 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-by: Ravishankar N <ravishankar@redhat.com> Tested-by: NetBSD Build System Reviewed-by: Kaushal M <kaushal@redhat.com> Tested-by: Kaushal M <kaushal@redhat.com>
* glusterd: support for tier volumes 'detach start' and 'detach commit'Dan Lambright2015-04-221-0/+60
| | | | | | | | | | | | | | | | | | | | | These commands work in a manner analagous to rebalancing when removing a brick. The existing migration daemon detects "detach start" and switches to moving data off the hot tier. While in this state all lookups are directed to the cold tier. gluster v detach-tier <vol> start gluster v detach-tier <vol> commit The status and stop cli commands shall be submitted separately. Change-Id: I24fda5cc3ba74f5fb8aa9a3234ad51f18b80a8a0 BUG: 1205540 Signed-off-by: Dan Lambright <dlambrig@redhat.com> Signed-off-by: root <root@localhost.localdomain> Signed-off-by: Dan Lambright <dlambrig@redhat.com> Reviewed-on: http://review.gluster.org/10108 Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Tested-by: NetBSD Build System
v>
default:
op = "";
@@ -1307,13 +660,14 @@ out:
return;
}
+
int
serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp)
{
gf_dirent_t *entry = NULL;
- gfs3_dirplist *trav = NULL;
- gfs3_dirplist *prev = NULL;
- int ret = -1;
+ gfs3_dirplist *trav = NULL;
+ gfs3_dirplist *prev = NULL;
+ int ret = -1;
GF_VALIDATE_OR_GOTO ("server", entries, out);
GF_VALIDATE_OR_GOTO ("server", rsp, out);
@@ -1367,10 +721,13 @@ serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp)
rsp->reply = trav;
prev = trav;
+ trav = NULL;
}
ret = 0;
out:
+ GF_FREE (trav);
+
return ret;
}
@@ -1378,10 +735,10 @@ out:
int
serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp)
{
- gf_dirent_t *entry = NULL;
- gfs3_dirlist *trav = NULL;
- gfs3_dirlist *prev = NULL;
- int ret = -1;
+ gf_dirent_t *entry = NULL;
+ gfs3_dirlist *trav = NULL;
+ gfs3_dirlist *prev = NULL;
+ int ret = -1;
GF_VALIDATE_OR_GOTO ("server", entries, out);
GF_VALIDATE_OR_GOTO ("server", rsp, out);
@@ -1408,11 +765,12 @@ out:
return ret;
}
+
int
readdir_rsp_cleanup (gfs3_readdir_rsp *rsp)
{
- gfs3_dirlist *prev = NULL;
- gfs3_dirlist *trav = NULL;
+ gfs3_dirlist *prev = NULL;
+ gfs3_dirlist *trav = NULL;
trav = rsp->reply;
prev = trav;
@@ -1425,6 +783,7 @@ readdir_rsp_cleanup (gfs3_readdir_rsp *rsp)
return 0;
}
+
int
readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
{
@@ -1435,6 +794,7 @@ readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
prev = trav;
while (trav) {
trav = trav->nextentry;
+ GF_FREE (prev->dict.dict_val);
GF_FREE (prev);
prev = trav;
}
@@ -1442,6 +802,7 @@ readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
return 0;
}
+
int
gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
{
@@ -1455,10 +816,14 @@ gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
if (fnmatch ("*list*mount*point*", key, 0) == 0) {
/* list all the client protocol connecting to this process */
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- gf_log ("mount-point-list", GF_LOG_INFO,
- "%s", xprt->peerinfo.identifier);
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ gf_log ("mount-point-list", GF_LOG_INFO,
+ "%s", xprt->peerinfo.identifier);
+ }
}
+ pthread_mutex_unlock (&conf->mutex);
}
/* Add more options/keys here */
@@ -1466,34 +831,431 @@ gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
return 0;
}
+
int
gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
{
- data_pair_t *pair = NULL;
- server_conf_t *conf = NULL;
- rpc_transport_t *xprt = NULL;
- uint64_t total_read = 0;
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+ uint64_t total_read = 0;
uint64_t total_write = 0;
conf = frame->this->private;
- if (!conf)
+ if (!conf || !dict)
return 0;
- for (pair = dict->members_list; pair; pair = pair->next) {
- /* this exact key is used in 'io-stats' too.
- * But this is better place for this information dump.
- */
- if (fnmatch ("*io*stat*dump", pair->key, 0) == 0) {
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- total_read += xprt->total_bytes_read;
- total_write += xprt->total_bytes_write;
- }
- gf_log ("stats", GF_LOG_INFO,
- "total-read %"PRIu64", total-write %"PRIu64,
- total_read, total_write);
+ if (dict_foreach_fnmatch (dict, "*io*stat*dump",
+ dict_null_foreach_fn, NULL ) > 0) {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ total_read += xprt->total_bytes_read;
+ total_write += xprt->total_bytes_write;
}
+ gf_log ("stats", GF_LOG_INFO,
+ "total-read %"PRIu64", total-write %"PRIu64,
+ total_read, total_write);
}
return 0;
}
+
+
+gf_boolean_t
+server_cancel_grace_timer (xlator_t *this, client_t *client)
+{
+ server_ctx_t *serv_ctx = NULL;
+ gf_timer_t *timer = NULL;
+ gf_boolean_t cancelled = _gf_false;
+
+ if (!this || !client) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Invalid arguments to cancel connection timer");
+ return cancelled;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (serv_ctx->grace_timer) {
+ timer = serv_ctx->grace_timer;
+ serv_ctx->grace_timer = NULL;
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
+
+ if (timer) {
+ gf_timer_call_cancel (this->ctx, timer);
+ cancelled = _gf_true;
+ }
+out:
+ return cancelled;
+}
+
+server_ctx_t*
+server_ctx_get (client_t *client, xlator_t *xlator)
+{
+ void *tmp = NULL;
+ server_ctx_t *ctx = NULL;
+
+ client_ctx_get (client, xlator, &tmp);
+
+ ctx = tmp;
+
+ if (ctx != NULL)
+ goto out;
+
+ ctx = GF_CALLOC (1, sizeof (server_ctx_t), gf_server_mt_server_conf_t);
+
+ if (ctx == NULL)
+ goto out;
+
+ /* ctx->lk_version = 0; redundant */
+ ctx->fdtable = gf_fd_fdtable_alloc ();
+
+ if (ctx->fdtable == NULL) {
+ GF_FREE (ctx);
+ ctx = NULL;
+ goto out;
+ }
+
+ LOCK_INIT (&ctx->fdtable_lock);
+
+ if (client_ctx_set (client, xlator, ctx) != 0) {
+ LOCK_DESTROY (&ctx->fdtable_lock);
+ GF_FREE (ctx);
+ ctx = NULL;
+ }
+
+out:
+ return ctx;
+}
+
+int32_t
+gf_barrier_transmit (server_conf_t *conf, gf_barrier_payload_t *payload)
+{
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ client_t *client = NULL;
+ gf_boolean_t lk_heal = _gf_false;
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ GF_VALIDATE_OR_GOTO ("barrier", conf, out);
+ GF_VALIDATE_OR_GOTO ("barrier", conf->barrier, out);
+ GF_VALIDATE_OR_GOTO ("barrier", payload, out);
+
+ barrier = conf->barrier;
+
+ frame = payload->frame;
+ if (frame) {
+ state = CALL_STATE (frame);
+ frame->local = NULL;
+ client = frame->root->client;
+ }
+ /* currently lk fops are not barrier'ed. This is reflecting code in
+ * server_submit_reply */
+ if (client)
+ lk_heal = ((server_conf_t *) client->this->private)->lk_heal;
+
+ ret = rpcsvc_submit_generic (payload->req, &payload->rsp, 1,
+ payload->payload, payload->payload_count,
+ payload->iobref);
+ iobuf_unref (payload->iob);
+ if (ret == -1) {
+ gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed");
+ if (frame && client && !lk_heal) {
+ server_connection_cleanup (frame->this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ } else {
+ /* TODO: Failure of open(dir), create, inodelk, entrylk
+ or lk fops send failure must be handled specially. */
+ }
+ goto ret;
+ }
+
+ ret = 0;
+ret:
+ if (state) {
+ free_state (state);
+ }
+
+ if (frame) {
+ gf_client_unref (client);
+ STACK_DESTROY (frame->root);
+ }
+
+ if (payload->free_iobref) {
+ iobref_unref (payload->iobref);
+ }
+out:
+ return ret;
+}
+
+gf_barrier_payload_t *
+gf_barrier_dequeue (gf_barrier_t *barrier)
+{
+ gf_barrier_payload_t *payload = NULL;
+
+ if (!barrier || list_empty (&barrier->queue))
+ return NULL;
+
+ payload = list_entry (barrier->queue.next,
+ gf_barrier_payload_t, list);
+ if (payload) {
+ list_del_init (&payload->list);
+ barrier->cur_size--;
+ }
+
+ return payload;
+}
+
+
+void*
+gf_barrier_dequeue_start (void *data)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_barrier_payload_t *payload = NULL;
+
+ conf = (server_conf_t *)data;
+ if (!conf || !conf->barrier)
+ return NULL;
+ barrier = conf->barrier;
+
+ LOCK (&barrier->lock);
+ {
+ while (barrier->cur_size) {
+ payload = gf_barrier_dequeue (barrier);
+ if (payload) {
+ if (gf_barrier_transmit (conf, payload)) {
+ gf_log ("server", GF_LOG_WARNING,
+ "Failed to transmit");
+ }
+ GF_FREE (payload);
+ }
+ }
+ }
+ UNLOCK (&barrier->lock);
+ return NULL;
+}
+
+void
+gf_barrier_timeout (void *data)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_boolean_t need_dequeue = _gf_false;
+
+ conf = (server_conf_t *)data;
+ if (!conf || !conf->barrier)
+ goto out;
+ barrier = conf->barrier;
+
+ gf_log ("", GF_LOG_INFO, "barrier timed-out");
+ LOCK (&barrier->lock);
+ {
+ need_dequeue = barrier->on;
+ barrier->on = _gf_false;
+ }
+ UNLOCK (&barrier->lock);
+
+ if (need_dequeue == _gf_true)
+ gf_barrier_dequeue_start (data);
+out:
+ return;
+}
+
+
+int32_t
+gf_barrier_start (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ struct timespec time = {0,};
+
+ conf = this->private;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out);
+
+ barrier = conf->barrier;
+
+ gf_log (this->name, GF_LOG_INFO, "barrier start called");
+ LOCK (&barrier->lock);
+ {
+ /* if barrier is on, reset timer */
+ if (barrier->on == _gf_true) {
+ ret = gf_timer_call_cancel (this->ctx, barrier->timer);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to "
+ "unset timer, failing barrier start");
+ goto unlock;
+ }
+ }
+
+ barrier->on = _gf_true;
+ time.tv_sec = barrier->time_out;
+ time.tv_nsec = 0;
+
+ barrier->timer = gf_timer_call_after (this->ctx, time,
+ gf_barrier_timeout,
+ (void *)conf);
+ if (!barrier->timer) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "timer, failing barrier start");
+ barrier->on = _gf_false;
+ }
+ }
+unlock:
+ UNLOCK (&barrier->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+gf_barrier_stop (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ int32_t ret = -1;
+ gf_boolean_t need_dequeue = _gf_false;
+
+ conf = this->private;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf->barrier, out);
+
+ barrier = conf->barrier;
+
+ gf_log (this->name, GF_LOG_INFO, "barrier stop called");
+ LOCK (&barrier->lock);
+ {
+ need_dequeue = barrier->on;
+ barrier->on = _gf_false;
+ }
+ UNLOCK (&barrier->lock);
+
+ if (need_dequeue == _gf_true) {
+ gf_timer_call_cancel (this->ctx, barrier->timer);
+ ret = gf_thread_create (&conf->barrier_th, NULL,
+ gf_barrier_dequeue_start,
+ conf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Failed to start un-barriering");
+ goto out;
+ }
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier, char *str)
+{
+ int32_t ret = -1;
+ char *dup_str = NULL;
+ char *str_tok = NULL;
+ char *save_ptr = NULL;
+ uint64_t fops = 0;
+
+ /* by defaul fsync & flush needs to be barriered */
+
+ fops |= 1 << GFS3_OP_FSYNC;
+ fops |= 1 << GFS3_OP_FLUSH;
+
+ if (!str)
+ goto done;
+
+ dup_str = gf_strdup (str);
+ if (!dup_str)
+ goto done;
+
+ str_tok = strtok_r (dup_str, ",", &save_ptr);
+ if (!str_tok)
+ goto done;
+
+ fops = 0;
+ while (str_tok) {
+ if (!strcmp(str_tok, "writev")) {
+ fops |= ((uint64_t)1 << GFS3_OP_WRITE);
+ } else if (!strcmp(str_tok, "fsync")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FSYNC);
+ } else if (!strcmp(str_tok, "read")) {
+ fops |= ((uint64_t)1 << GFS3_OP_READ);
+ } else if (!strcmp(str_tok, "rename")) {
+ fops |= ((uint64_t)1 << GFS3_OP_RENAME);
+ } else if (!strcmp(str_tok, "flush")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FLUSH);
+ } else if (!strcmp(str_tok, "ftruncate")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FTRUNCATE);
+ } else if (!strcmp(str_tok, "fallocate")) {
+ fops |= ((uint64_t)1 << GFS3_OP_FALLOCATE);
+ } else if (!strcmp(str_tok, "rmdir")) {
+ fops |= ((uint64_t)1 << GFS3_OP_RMDIR);
+ } else {
+ gf_log ("barrier", GF_LOG_ERROR,
+ "Invalid barrier fop %s", str_tok);
+ }
+
+ str_tok = strtok_r (NULL, ",", &save_ptr);
+ }
+done:
+ LOCK (&barrier->lock);
+ {
+ barrier->fops = fops;
+ }
+ UNLOCK (&barrier->lock);
+ ret = 0;
+
+ GF_FREE (dup_str);
+ return ret;
+}
+
+void
+gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *payload)
+{
+ list_add_tail (&payload->list, &barrier->queue);
+ barrier->cur_size++;
+}
+
+gf_barrier_payload_t *
+gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp,
+ call_frame_t *frame, struct iovec *payload_orig,
+ int payloadcount, struct iobref *iobref,
+ struct iobuf *iob, gf_boolean_t free_iobref)
+{
+ gf_barrier_payload_t *payload = NULL;
+
+ if (!rsp)
+ return NULL;
+
+ payload = GF_CALLOC (1, sizeof (*payload),1);
+ if (!payload)
+ return NULL;
+
+ INIT_LIST_HEAD (&payload->list);
+
+ payload->req = req;
+ memcpy (&payload->rsp, rsp, sizeof (struct iovec));
+ payload->frame = frame;
+ payload->payload = payload_orig;
+ payload->payload_count = payloadcount;
+ payload->iobref = iobref;
+ payload->iob = iob;
+ payload->free_iobref = free_iobref;
+
+ return payload;
+}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 844c98c27..b455aa6df 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _SERVER_HELPERS_H
@@ -24,13 +15,8 @@
#define CALL_STATE(frame) ((server_state_t *)frame->root->state)
-#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->conn->bound_xl)
-
#define XPRT_FROM_FRAME(frame) ((rpc_transport_t *) CALL_STATE(frame)->xprt)
-#define SERVER_CONNECTION(frame) \
- ((server_connection_t *) CALL_STATE(frame)->conn)
-
#define SERVER_CONF(frame) \
((server_conf_t *)XPRT_FROM_FRAME(frame)->this->private)
@@ -43,39 +29,26 @@
#define IS_NOT_ROOT(pathlen) ((pathlen > 2)? 1 : 0)
+#define is_fop_barriered(fops, procnum) (fops & ((uint64_t)1 << procnum))
+
+#define barrier_add_to_queue(barrier) (barrier->on || barrier->cur_size)
+
void free_state (server_state_t *state);
void server_loc_wipe (loc_t *loc);
-int32_t
-gf_add_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- pid_t pid,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
-int32_t
-gf_del_locker (struct _lock_table *table, const char *volume,
- loc_t *loc,
- fd_t *fd,
- gf_lkowner_t *owner,
- glusterfs_fop_t type);
-
void
server_print_request (call_frame_t *frame);
call_frame_t *
get_frame_from_request (rpcsvc_request_t *req);
-server_connection_t *
-get_server_conn_state (xlator_t *this, rpc_transport_t *xptr);
+int
+server_connection_cleanup (xlator_t *this, struct _client_t *client,
+ int32_t flags);
-server_connection_t *
-create_server_conn_state (xlator_t *this, rpc_transport_t *xptr);
-
-void
-destroy_server_conn_state (server_connection_t *conn);
+gf_boolean_t
+server_cancel_grace_timer (xlator_t *this, struct _client_t *client);
int
server_build_config (xlator_t *this, server_conf_t *conf);
@@ -85,4 +58,17 @@ int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp);
int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp);
int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp);
+server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator);
+
+int32_t gf_barrier_start (xlator_t *this);
+int32_t gf_barrier_stop (xlator_t *this);
+int32_t gf_barrier_fops_configure (xlator_t *this, gf_barrier_t *barrier,
+ char *str);
+void gf_barrier_enqueue (gf_barrier_t *barrier, gf_barrier_payload_t *stub);
+gf_barrier_payload_t *
+gf_barrier_payload (rpcsvc_request_t *req, struct iovec *rsp,
+ call_frame_t *frame, struct iovec *payload,
+ int payloadcount, struct iobref *iobref,
+ struct iobuf *iob, gf_boolean_t free_iobref);
+
#endif /* !_SERVER_HELPERS_H */
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
index 88bae8cb4..19c3466d3 100644
--- a/xlators/protocol/server/src/server-mem-types.h
+++ b/xlators/protocol/server/src/server-mem-types.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -33,6 +24,7 @@ enum gf_server_mem_types_ {
gf_server_mt_dirent_rsp_t,
gf_server_mt_rsp_buf_t,
gf_server_mt_volfile_ctx_t,
+ gf_server_mt_timer_data_t,
gf_server_mt_end,
};
#endif /* __SERVER_MEM_TYPES_H__ */
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 38ab368c3..cc4686a03 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -70,7 +61,8 @@ resolve_loc_touchup (call_frame_t *frame)
int
resolve_gfid_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr, struct iatt *postparent)
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *postparent)
{
server_state_t *state = NULL;
server_resolve_t *resolve = NULL;
@@ -111,7 +103,7 @@ out:
int
resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent)
+ dict_t *xdata, struct iatt *postparent)
{
server_state_t *state = NULL;
server_resolve_t *resolve = NULL;
@@ -155,7 +147,8 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
(char **) &resolve_loc->path);
STACK_WIND (frame, resolve_gfid_entry_cbk,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
&resolve->resolve_loc, NULL);
return 0;
out:
@@ -178,25 +171,21 @@ resolve_gfid (call_frame_t *frame)
resolve = state->resolve_now;
resolve_loc = &resolve->resolve_loc;
- if (!uuid_is_null (resolve->pargfid)) {
+ if (!uuid_is_null (resolve->pargfid))
uuid_copy (resolve_loc->gfid, resolve->pargfid);
- resolve_loc->inode = inode_new (state->itable);
- ret = inode_path (resolve_loc->inode, NULL,
- (char **)&resolve_loc->path);
- } else if (!uuid_is_null (resolve->gfid)) {
+ else if (!uuid_is_null (resolve->gfid))
uuid_copy (resolve_loc->gfid, resolve->gfid);
- resolve_loc->inode = inode_new (state->itable);
- ret = inode_path (resolve_loc->inode, NULL,
- (char **)&resolve_loc->path);
- }
+
+ resolve_loc->inode = inode_new (state->itable);
+ ret = loc_path (resolve_loc, NULL);
STACK_WIND (frame, resolve_gfid_cbk,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
&resolve->resolve_loc, NULL);
return 0;
}
-
int
resolve_continue (call_frame_t *frame)
{
@@ -426,6 +415,10 @@ out:
if (inode)
inode_unref (inode);
+ if (ret != 0)
+ gf_log ("server", GF_LOG_WARNING, "inode for the gfid (%s) is "
+ "not found. anonymous fd creation failed",
+ uuid_utoa (resolve->gfid));
return ret;
}
@@ -458,23 +451,34 @@ server_resolve_anonfd (call_frame_t *frame)
int
server_resolve_fd (call_frame_t *frame)
{
- server_state_t *state = NULL;
- server_resolve_t *resolve = NULL;
- server_connection_t *conn = NULL;
- uint64_t fd_no = -1;
+ server_ctx_t *serv_ctx = NULL;
+ server_state_t *state = NULL;
+ client_t *client = NULL;
+ server_resolve_t *resolve = NULL;
+ uint64_t fd_no = -1;
state = CALL_STATE (frame);
resolve = state->resolve_now;
- conn = SERVER_CONNECTION (frame);
fd_no = resolve->fd_no;
- if (fd_no == -2) {
+ if (fd_no == GF_ANON_FD_NO) {
server_resolve_anonfd (frame);
return 0;
}
- state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no);
+ client = frame->root->client;
+
+ serv_ctx = server_ctx_get (client, client->this);
+
+ if (serv_ctx == NULL) {
+ gf_log ("", GF_LOG_INFO, "server_ctx_get() failed");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOMEM;
+ return 0;
+ }
+
+ state->fd = gf_fd_fdptr_get (serv_ctx->fdtable, fd_no);
if (!state->fd) {
gf_log ("", GF_LOG_INFO, "fd not found in context");
@@ -529,14 +533,12 @@ int
server_resolve_done (call_frame_t *frame)
{
server_state_t *state = NULL;
- xlator_t *bound_xl = NULL;
state = CALL_STATE (frame);
- bound_xl = BOUND_XL (frame);
server_print_request (frame);
- state->resume_fn (frame, bound_xl);
+ state->resume_fn (frame, frame->root->client->bound_xl);
return 0;
}
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
new file mode 100644
index 000000000..138e601ce
--- /dev/null
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -0,0 +1,6179 @@
+/*
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <openssl/md5.h>
+
+#include "server.h"
+#include "server-helpers.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include "compat-errno.h"
+
+#include "xdr-nfs3.h"
+
+#define SERVER_REQ_SET_ERROR(req, ret) \
+ do { \
+ rpcsvc_request_seterr (req, GARBAGE_ARGS); \
+ ret = RPCSVC_ACTOR_ERROR; \
+ } while (0)
+
+/* Callback function section */
+int
+server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
+{
+ gfs3_statfs_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING, "%"PRId64": STATFS (%s)",
+ frame->root->unique, strerror (op_errno));
+ goto out;
+ }
+
+ gf_statfs_from_statfs (&rsp.statfs, buf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_statfs_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xdata,
+ struct iatt *postparent)
+{
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+ inode_t *root_inode = NULL;
+ inode_t *link_inode = NULL;
+ loc_t fresh_loc = {0,};
+ gfs3_lookup_rsp rsp = {0,};
+ uuid_t rootgfid = {0,};
+
+ state = CALL_STATE (frame);
+
+ if (state->is_revalidate == 1 && op_ret == -1) {
+ state->is_revalidate = 2;
+ loc_copy (&fresh_loc, &state->loc);
+ inode_unref (fresh_loc.inode);
+ fresh_loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_lookup_cbk,
+ frame->root->client->bound_xl,
+ frame->root->client->bound_xl->fops->lookup,
+ &fresh_loc, state->xdata);
+
+ loc_wipe (&fresh_loc);
+ return 0;
+ }
+
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ if (state->is_revalidate && op_errno == ENOENT) {
+ if (!__is_root_gfid (state->resolve.gfid)) {
+ inode_unlink (state->loc.inode,
+ state->loc.parent,
+ state->loc.name);
+ }
+ }
+ goto out;
+ }
+
+ root_inode = frame->root->client->bound_xl->itable->root;
+ if (inode == root_inode) {
+ /* we just looked up root ("/") */
+ stbuf->ia_ino = 1;
+ rootgfid[15] = 1;
+ uuid_copy (stbuf->ia_gfid, rootgfid);
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+ if (!__is_root_gfid (inode->gfid)) {
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ if (link_inode) {
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ }
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ if (op_ret) {
+ if (state->resolve.bname) {
+ gf_log (this->name, ((op_errno == ENOENT) ?
+ GF_LOG_TRACE : GF_LOG_INFO),
+ "%"PRId64": LOOKUP %s (%s/%s) ==> "
+ "(%s)", frame->root->unique,
+ state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, ((op_errno == ENOENT) ?
+ GF_LOG_TRACE : GF_LOG_INFO),
+ "%"PRId64": LOOKUP %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ }
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lookup_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
+{
+ gfs3_lk_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LK %"PRId64" (%s) ==> "
+ "(%s)", frame->root->unique,
+ state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+ switch (lock->l_type) {
+ case F_RDLCK:
+ lock->l_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ lock->l_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ lock->l_type = GF_LK_F_UNLCK;
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unknown lock type: %"PRId32"!", lock->l_type);
+ break;
+ }
+
+ gf_proto_flock_from_flock (&rsp.flock, lock);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_lk_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": INODELK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FINODELK %"PRId64" (%s) "
+ "==> (%s)", frame->root->unique,
+ state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ENTRYLK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FENTRYLK %"PRId64" (%s) ==>(%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ }
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ACCESS %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_rmdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *parent = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RMDIR %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ /* parent should not be found for directories after
+ * inode_unlink, since directories cannot have
+ * hardlinks.
+ */
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rmdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_mkdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": MKDIR %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_mkdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_mknod_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": MKNOD %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_mknod_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ gfs3_readdir_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READDIR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = serialize_rsp_dirent (entries, &rsp);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readdir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ readdir_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+int
+server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfs3_opendir_rsp rsp = {0,};
+ uint64_t fd_no = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": OPENDIR %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd); // on behalf of the client
+
+out:
+ rsp.fd = fd_no;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_opendir_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": REMOVEXATTR %s (%s) of key %s ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FREMOVEXATTR %"PRId64" (%s) (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), state->name,
+ strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_getxattr_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (((op_errno == ENOTSUP) ||
+ (op_errno == ENODATA) ||
+ (op_errno == ENOENT)) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%"PRId64": GETXATTR %s (%s) (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_getxattr_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_fgetxattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%"PRId64": FGETXATTR %"PRId64" (%s) (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ state->name, strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+/* print every key */
+static int
+_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+
+ frame = tmp;
+ state = CALL_STATE (frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": SETXATTR %s (%s) ==> %s",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), k);
+ return 0;
+}
+
+int
+server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ if (op_errno != ENOTSUP)
+ dict_foreach (state->dict,
+ _gf_server_log_setxattr_failure,
+ frame);
+
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+/* print every key here */
+static int
+_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ frame = tmp;
+ state = CALL_STATE (frame);
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), k);
+
+ return 0;
+}
+
+int
+server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret == -1) {
+ state = CALL_STATE (frame);
+ if (op_errno != ENOTSUP) {
+ dict_foreach (state->dict,
+ _gf_server_log_fsetxattr_failure,
+ frame);
+ }
+ gf_log (THIS->name, ((op_errno == ENOTSUP) ?
+ GF_LOG_DEBUG : GF_LOG_INFO),
+ "%s", strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
+{
+ gfs3_rename_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ inode_t *tmp_inode = NULL;
+ inode_t *tmp_parent = NULL;
+ char oldpar_str[50] = {0,};
+ char newpar_str[50] = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret == -1) {
+ uuid_utoa_r (state->resolve.gfid, oldpar_str);
+ uuid_utoa_r (state->resolve2.gfid, newpar_str);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RENAME %s (%s/%s) -> %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ oldpar_str, state->resolve.bname, state->loc2.path,
+ newpar_str, state->resolve2.bname, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf->ia_type = state->loc.inode->ia_type;
+
+ /* TODO: log gfid of the inodes */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": RENAME_CBK %s ==> %s",
+ frame->root->unique, state->loc.name, state->loc2.name);
+
+ /* Before renaming the inode, we have to get the inode for the
+ * destination entry (i.e. inode with state->loc2.parent as
+ * parent and state->loc2.name as name). If it exists, then
+ * unlink that inode, and send forget on that inode if the
+ * unlinked entry is the last entry. In case of fuse client
+ * the fuse kernel module itself sends the forget on the
+ * unlinked inode.
+ */
+ tmp_inode = inode_grep (state->loc.inode->table,
+ state->loc2.parent, state->loc2.name);
+ if (tmp_inode) {
+ inode_unlink (tmp_inode, state->loc2.parent,
+ state->loc2.name);
+ tmp_parent = inode_parent (tmp_inode, 0, NULL);
+ if (tmp_parent)
+ inode_unref (tmp_parent);
+ else
+ inode_forget (tmp_inode, 0);
+
+ inode_unref (tmp_inode);
+ }
+
+ inode_rename (state->itable,
+ state->loc.parent, state->loc.name,
+ state->loc2.parent, state->loc2.name,
+ state->loc.inode, stbuf);
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+ gf_stat_from_iatt (&rsp.preoldparent, preoldparent);
+ gf_stat_from_iatt (&rsp.postoldparent, postoldparent);
+
+ gf_stat_from_iatt (&rsp.prenewparent, prenewparent);
+ gf_stat_from_iatt (&rsp.postnewparent, postnewparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rename_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_unlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *parent = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": UNLINK %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ /* TODO: log gfid of the inodes */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": UNLINK_CBK %s",
+ frame->root->unique, state->loc.name);
+
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_unlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_symlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": SYMLINK %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_symlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ gfs3_link_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ char gfid_str[50] = {0,};
+ char newpar_str[50] = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret) {
+ uuid_utoa_r (state->resolve.gfid, gfid_str);
+ uuid_utoa_r (state->resolve2.pargfid, newpar_str);
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LINK %s (%s) -> %s/%s ==> (%s)",
+ frame->root->unique, state->loc.path,
+ gfid_str, newpar_str, state->resolve2.bname,
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc2.parent,
+ state->loc2.name, stbuf);
+ inode_unref (link_inode);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_link_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_truncate_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": TRUNCATE %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_truncate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ gfs3_fstat_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSTAT %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fstat_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_ftruncate_rsp rsp = {0};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FTRUNCATE %"PRId64" (%s)==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_ftruncate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ gf_common_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": FLUSH %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_fsync_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSYNC %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&(rsp.prestat), prebuf);
+ gf_stat_from_iatt (&(rsp.poststat), postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsync_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ gfs3_write_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": WRITEV %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_write_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+{
+ gfs3_read_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+#ifdef GF_TESTING_IO_XDATA
+ {
+ int ret = 0;
+ if (!xdata)
+ xdata = dict_new ();
+
+ ret = dict_set_str (xdata, "testing-the-xdata-key",
+ "testing-xdata-value");
+ }
+#endif
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READV %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ rsp.size = op_ret;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, vector, count, iobref,
+ (xdrproc_t)xdr_gfs3_read_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ uint32_t weak_checksum, uint8_t *strong_checksum,
+ dict_t *xdata)
+{
+ gfs3_rchecksum_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+ server_state_t *state = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RCHECKSUM %"PRId64" (%s)==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid), strerror (op_errno));
+ goto out;
+ }
+
+ rsp.weak_checksum = weak_checksum;
+
+ rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum;
+ rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_rchecksum_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ rpcsvc_request_t *req = NULL;
+ uint64_t fd_no = 0;
+ gfs3_open_rsp rsp = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": OPEN %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd);
+ rsp.fd = fd_no;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_open_rsp);
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ uint64_t fd_no = 0;
+ gfs3_create_rsp rsp = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": CREATE %s (%s/%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.pargfid),
+ state->resolve.bname, strerror (op_errno));
+ goto out;
+ }
+
+ /* TODO: log gfid too */
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": CREATE %s (%s)",
+ frame->root->unique, state->loc.name,
+ uuid_utoa (stbuf->ia_gfid));
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+
+ if (!link_inode) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ if (link_inode != inode) {
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
+
+ inode_unref (fd->inode);
+ fd->inode = inode_ref (link_inode);
+ }
+
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+ serv_ctx = server_ctx_get (frame->root->client, this);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
+ fd_ref (fd);
+
+ if ((fd_no < 0) || (fd == 0)) {
+ op_ret = fd_no;
+ op_errno = errno;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+out:
+ rsp.fd = fd_no;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_create_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *buf,
+ struct iatt *stbuf, dict_t *xdata)
+{
+ gfs3_readlink_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READLINK %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.buf, stbuf);
+ rsp.path = (char *)buf;
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ if (!rsp.path)
+ rsp.path = "";
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readlink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ gfs3_stat_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, (op_errno == ENOENT)?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "%"PRId64": STAT %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_stat_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_setattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": SETATTR %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_setattr_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_fsetattr_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSETATTR %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fsetattr_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_xattrop_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": XATTROP %s (%s) ==> (%s)",
+ frame->root->unique, state->loc.path,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_xattrop_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ gfs3_xattrop_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FXATTROP %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
+ rsp.dict.dict_len, op_errno, out);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_fxattrop_rsp);
+
+ GF_FREE (rsp.dict.dict_val);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+int
+server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ gfs3_readdirp_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = 0;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": READDIRP %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ /* (op_ret == 0) is valid, and means EOF */
+ if (op_ret) {
+ ret = serialize_rsp_direntp (entries, &rsp);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ /* TODO: need more clear thoughts before calling this function. */
+ /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs3_readdirp_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ readdirp_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+int
+server_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_fallocate_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FALLOCATE %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_fallocate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_discard_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ state = CALL_STATE (frame);
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": DISCARD %"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_discard_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+{
+ gfs3_zerofill_rsp rsp = {0,};
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+
+ req = frame->local;
+ state = CALL_STATE (frame);
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ZEROFILL%"PRId64" (%s) ==> (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs3_zerofill_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+
+/* Resume function section */
+
+int
+server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = EINVAL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rchecksum_cbk, bound_xl,
+ bound_xl->fops->rchecksum, state->fd,
+ state->offset, state->size, state->xdata);
+
+ return 0;
+err:
+ server_rchecksum_cbk (frame, NULL, frame->this, op_ret, op_errno, 0,
+ NULL, NULL);
+
+ return 0;
+
+}
+
+int
+server_lk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_lk_cbk, bound_xl, bound_xl->fops->lk,
+ state->fd, state->cmd, &state->flock, state->xdata);
+
+ return 0;
+
+err:
+ server_lk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_rename_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rename_cbk,
+ bound_xl, bound_xl->fops->rename,
+ &state->loc, &state->loc2, state->xdata);
+ return 0;
+err:
+ server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_link_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ state->loc2.inode = inode_ref (state->loc.inode);
+
+ STACK_WIND (frame, server_link_cbk, bound_xl, bound_xl->fops->link,
+ &state->loc, &state->loc2, state->xdata);
+
+ return 0;
+err:
+ server_link_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_symlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_symlink_cbk,
+ bound_xl, bound_xl->fops->symlink,
+ state->name, &state->loc, state->umask, state->xdata);
+
+ return 0;
+err:
+ server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_access_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_access_cbk,
+ bound_xl, bound_xl->fops->access,
+ &state->loc, state->mask, state->xdata);
+ return 0;
+err:
+ server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_fentrylk_cbk, bound_xl,
+ bound_xl->fops->fentrylk,
+ state->volume, state->fd, state->name,
+ state->cmd, state->type, state->xdata);
+
+ return 0;
+err:
+ server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_entrylk_cbk,
+ bound_xl, bound_xl->fops->entrylk,
+ state->volume, &state->loc, state->name,
+ state->cmd, state->type, state->xdata);
+ return 0;
+err:
+ server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p",
+ frame, bound_xl);
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_finodelk_cbk, bound_xl,
+ bound_xl->fops->finodelk, state->volume, state->fd,
+ state->cmd, &state->flock, state->xdata);
+
+ return 0;
+err:
+ server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ GF_UNUSED int ret = -1;
+ server_state_t *state = NULL;
+
+ gf_log (bound_xl->name, GF_LOG_WARNING, "frame %p, xlator %p",
+ frame, bound_xl);
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->xdata)
+ state->xdata = dict_new ();
+
+ if (state->xdata)
+ ret = dict_set_str (state->xdata, "connection-id",
+ frame->root->client->client_uid);
+
+ STACK_WIND (frame, server_inodelk_cbk, bound_xl,
+ bound_xl->fops->inodelk, state->volume, &state->loc,
+ state->cmd, &state->flock, state->xdata);
+ return 0;
+err:
+ server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_rmdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_rmdir_cbk, bound_xl, bound_xl->fops->rmdir,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_mkdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mkdir_cbk,
+ bound_xl, bound_xl->fops->mkdir,
+ &(state->loc), state->mode, state->umask, state->xdata);
+
+ return 0;
+err:
+ server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_mknod_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mknod_cbk,
+ bound_xl, bound_xl->fops->mknod,
+ &(state->loc), state->mode, state->dev,
+ state->umask, state->xdata);
+
+ return 0;
+err:
+ server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_fsyncdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsyncdir_cbk,
+ bound_xl,
+ bound_xl->fops->fsyncdir,
+ state->fd, state->flags, state->xdata);
+ return 0;
+
+err:
+ server_fsyncdir_cbk (frame, NULL, frame->this,
+ state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+int
+server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ GF_ASSERT (state->fd);
+
+ STACK_WIND (frame, server_readdir_cbk,
+ bound_xl,
+ bound_xl->fops->readdir,
+ state->fd, state->size, state->offset, state->xdata);
+
+ return 0;
+err:
+ server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readdirp_cbk, bound_xl,
+ bound_xl->fops->readdirp, state->fd, state->size,
+ state->offset, state->dict);
+
+ return 0;
+err:
+ server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ if (!state->fd) {
+ gf_log ("server", GF_LOG_ERROR, "could not create the fd");
+ goto err;
+ }
+
+ STACK_WIND (frame, server_opendir_cbk,
+ bound_xl, bound_xl->fops->opendir,
+ &state->loc, state->fd, state->xdata);
+ return 0;
+err:
+ server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_statfs_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret !=0)
+ goto err;
+
+ STACK_WIND (frame, server_statfs_cbk,
+ bound_xl, bound_xl->fops->statfs,
+ &state->loc, state->xdata);
+ return 0;
+
+err:
+ server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_removexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_removexattr_cbk,
+ bound_xl, bound_xl->fops->removexattr,
+ &state->loc, state->name, state->xdata);
+ return 0;
+err:
+ server_removexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fremovexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fremovexattr_cbk,
+ bound_xl, bound_xl->fops->fremovexattr,
+ state->fd, state->name, state->xdata);
+ return 0;
+err:
+ server_fremovexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+int
+server_fgetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fgetxattr_cbk,
+ bound_xl, bound_xl->fops->fgetxattr,
+ state->fd, state->name, state->xdata);
+ return 0;
+err:
+ server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_xattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_xattrop_cbk,
+ bound_xl, bound_xl->fops->xattrop,
+ &state->loc, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_fxattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fxattrop_cbk,
+ bound_xl, bound_xl->fops->fxattrop,
+ state->fd, state->flags, state->dict, state->xdata);
+ return 0;
+err:
+ server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_fsetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->fsetxattr,
+ state->fd, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+int
+server_unlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_unlink_cbk,
+ bound_xl, bound_xl->fops->unlink,
+ &state->loc, state->flags, state->xdata);
+ return 0;
+err:
+ server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_truncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_truncate_cbk,
+ bound_xl, bound_xl->fops->truncate,
+ &state->loc, state->offset, state->xdata);
+ return 0;
+err:
+ server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+int
+server_fstat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fstat_cbk,
+ bound_xl, bound_xl->fops->fstat,
+ state->fd, state->xdata);
+ return 0;
+err:
+ server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->setxattr,
+ &state->loc, state->dict, state->flags, state->xdata);
+ return 0;
+err:
+ server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+server_getxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_getxattr_cbk,
+ bound_xl, bound_xl->fops->getxattr,
+ &state->loc, state->name, state->xdata);
+ return 0;
+err:
+ server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_ftruncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_ftruncate_cbk,
+ bound_xl, bound_xl->fops->ftruncate,
+ state->fd, state->offset, state->xdata);
+ return 0;
+err:
+ server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_flush_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_flush_cbk,
+ bound_xl, bound_xl->fops->flush, state->fd, state->xdata);
+ return 0;
+err:
+ server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+server_fsync_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsync_cbk,
+ bound_xl, bound_xl->fops->fsync,
+ state->fd, state->flags, state->xdata);
+ return 0;
+err:
+ server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_writev_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_writev_cbk,
+ bound_xl, bound_xl->fops->writev,
+ state->fd, state->payload_vector, state->payload_count,
+ state->offset, state->flags, state->iobref, state->xdata);
+
+ return 0;
+err:
+ server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_readv_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readv_cbk,
+ bound_xl, bound_xl->fops->readv,
+ state->fd, state->size, state->offset, state->flags, state->xdata);
+
+ return 0;
+err:
+ server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, 0, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_create_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ if (!state->fd) {
+ gf_log ("server", GF_LOG_ERROR, "fd creation for the inode %s "
+ "failed", state->loc.inode?
+ uuid_utoa (state->loc.inode->gfid):NULL);
+ state->resolve.op_ret = -1;
+ state->resolve.op_errno = ENOMEM;
+ goto err;
+ }
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_create_cbk,
+ bound_xl, bound_xl->fops->create,
+ &(state->loc), state->flags, state->mode,
+ state->umask, state->fd, state->xdata);
+
+ return 0;
+err:
+ server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_open_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_open_cbk,
+ bound_xl, bound_xl->fops->open,
+ &state->loc, state->flags, state->fd, state->xdata);
+
+ return 0;
+err:
+ server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_readlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readlink_cbk,
+ bound_xl, bound_xl->fops->readlink,
+ &state->loc, state->size, state->xdata);
+ return 0;
+err:
+ server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+server_fsetattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsetattr_cbk,
+ bound_xl, bound_xl->fops->fsetattr,
+ state->fd, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_setattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setattr_cbk,
+ bound_xl, bound_xl->fops->setattr,
+ &state->loc, &state->stbuf, state->valid, state->xdata);
+ return 0;
+err:
+ server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+server_stat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_stat_cbk,
+ bound_xl, bound_xl->fops->stat, &state->loc, state->xdata);
+ return 0;
+err:
+ server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+int
+server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->itable);
+ else
+ state->is_revalidate = 1;
+
+ STACK_WIND (frame, server_lookup_cbk,
+ bound_xl, bound_xl->fops->lookup,
+ &state->loc, state->xdata);
+
+ return 0;
+err:
+ server_lookup_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_fallocate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fallocate_cbk,
+ bound_xl, bound_xl->fops->fallocate,
+ state->fd, state->flags, state->offset, state->size,
+ state->xdata);
+ return 0;
+err:
+ server_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_discard_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_discard_cbk,
+ bound_xl, bound_xl->fops->discard,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_zerofill_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_zerofill_cbk,
+ bound_xl, bound_xl->fops->zerofill,
+ state->fd, state->offset, state->size, state->xdata);
+ return 0;
+err:
+ server_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+
+/* Fop section */
+
+int
+server3_3_stat (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_stat_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return 0;
+
+ /* Initialize args first, then decode */
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_STAT;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+
+ ret = 0;
+ resolve_and_resume (frame, server_stat_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_setattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_setattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return 0;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_setattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SETATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ gf_stat_to_iatt (&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_setattr_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_fsetattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsetattr_req args = {0,};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsetattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSETATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ gf_stat_to_iatt (&args.stbuf, &state->stbuf);
+ state->valid = args.valid;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsetattr_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fallocate(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fallocate_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fallocate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FALLOCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->flags = args.flags;
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fallocate_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_discard(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_discard_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_discard_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_DISCARD;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_discard_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_zerofill(rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_zerofill_req args = {{0},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_zerofill_req);
+ if (ret < 0) {
+ /*failed to decode msg*/;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ /* something wrong, mostly insufficient memory*/
+ req->rpc_err = GARBAGE_ARGS; /* TODO */
+ goto out;
+ }
+ frame->root->op = GF_FOP_ZEROFILL;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+
+ state->offset = args.offset;
+ state->size = args.size;
+ memcpy(state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, state->xdata,
+ (args.xdata.xdata_val),
+ (args.xdata.xdata_len), ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_zerofill_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ req->rpc_err = GARBAGE_ARGS;
+
+ return ret;
+}
+
+int
+server3_3_readlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ state->size = args.size;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readlink_resume);
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_create (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_create_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_create_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_CREATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+
+ state->resolve.bname = gf_strdup (args.bname);
+ state->mode = args.mode;
+ state->umask = args.umask;
+ state->flags = gf_flags_to_flags (args.flags);
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+
+ if (state->flags & O_EXCL) {
+ state->resolve.type = RESOLVE_NOT;
+ } else {
+ state->resolve.type = RESOLVE_DONTCARE;
+ }
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_create_resume);
+
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_open (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_open_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_OPEN;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ state->flags = gf_flags_to_flags (args.flags);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_open_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_readv (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_read_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ goto out;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READ;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->size = args.size;
+ state->offset = args.offset;
+ state->flags = args.flag;
+
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readv_resume);
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_writev (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_write_req args = {{0,},};
+ ssize_t len = 0;
+ int i = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ len = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_write_req);
+ if (len < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_WRITE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->flags = args.flag;
+ state->iobref = iobref_ref (req->iobref);
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (len < req->msg[0].iov_len) {
+ state->payload_vector[0].iov_base
+ = (req->msg[0].iov_base + len);
+ state->payload_vector[0].iov_len
+ = req->msg[0].iov_len - len;
+ state->payload_count = 1;
+ }
+
+ for (i = 1; i < req->count; i++) {
+ state->payload_vector[state->payload_count++]
+ = req->msg[i];
+ }
+
+ for (i = 0; i < state->payload_count; i++) {
+ state->size += state->payload_vector[i].iov_len;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+#ifdef GF_TESTING_IO_XDATA
+ dict_dump (state->xdata);
+#endif
+
+ ret = 0;
+ resolve_and_resume (frame, server_writev_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+#define SERVER3_3_VECWRITE_START 0
+#define SERVER3_3_VECWRITE_READING_HDR 1
+#define SERVER3_3_VECWRITE_READING_OPAQUE 2
+
+int
+server3_3_writev_vecsizer (int state, ssize_t *readsize, char *base_addr,
+ char *curr_addr)
+{
+ ssize_t size = 0;
+ int nextstate = 0;
+ gfs3_write_req write_req = {{0,},};
+ XDR xdr;
+
+ switch (state) {
+ case SERVER3_3_VECWRITE_START:
+ size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
+ &write_req);
+ *readsize = size;
+ nextstate = SERVER3_3_VECWRITE_READING_HDR;
+ break;
+ case SERVER3_3_VECWRITE_READING_HDR:
+ size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
+ &write_req);
+
+ xdrmem_create (&xdr, base_addr, size, XDR_DECODE);
+
+ /* This will fail if there is xdata sent from client, if not,
+ well and good */
+ xdr_gfs3_write_req (&xdr, &write_req);
+
+ /* need to round off to proper roof (%4), as XDR packing pads
+ the end of opaque object with '0' */
+ size = roof (write_req.xdata.xdata_len, 4);
+
+ *readsize = size;
+
+ if (!size)
+ nextstate = SERVER3_3_VECWRITE_START;
+ else
+ nextstate = SERVER3_3_VECWRITE_READING_OPAQUE;
+
+ free (write_req.xdata.xdata_val);
+
+ break;
+
+ case SERVER3_3_VECWRITE_READING_OPAQUE:
+ *readsize = 0;
+ nextstate = SERVER3_3_VECWRITE_START;
+ break;
+ default:
+ gf_log ("server", GF_LOG_ERROR, "wrong state: %d", state);
+ }
+
+ return nextstate;
+}
+
+
+int
+server3_3_release (rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfs3_release_req args = {{0,},};
+ gf_common_rsp rsp = {0,};
+ int ret = -1;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_release_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ client = req->trans->xl_private;
+ if (!client) {
+ /* Handshake is not complete yet. */
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (req->trans->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ gf_fd_put (serv_ctx->fdtable, args.fd);
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+server3_3_releasedir (rpcsvc_request_t *req)
+{
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gfs3_releasedir_req args = {{0,},};
+ gf_common_rsp rsp = {0,};
+ int ret = -1;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_release_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ client = req->trans->xl_private;
+ if (!client) {
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ serv_ctx = server_ctx_get (client, client->this);
+ if (serv_ctx == NULL) {
+ gf_log (req->trans->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ req->rpc_err = SYSTEM_ERR;
+ goto out;
+ }
+
+ gf_fd_put (serv_ctx->fdtable, args.fd);
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+server3_3_fsync (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsync_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsync_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSYNC;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsync_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_flush (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_flush_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_flush_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FLUSH;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_flush_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_ftruncate (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_ftruncate_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_ftruncate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FTRUNCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_ftruncate_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_fstat (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fstat_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fstat_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSTAT;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fstat_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_truncate (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_truncate_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_truncate_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_TRUNCATE;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->offset = args.offset;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_truncate_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_unlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_unlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_unlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_UNLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup (args.bname);
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+
+ state->flags = args.xflags;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_unlink_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_setxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_setxattr_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_setxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ /* There can be some commands hidden in key, check and proceed */
+ gf_server_check_setxattr_cmd (frame, dict);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_setxattr_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_fsetxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsetxattr_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsetxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsetxattr_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_fxattrop (rpcsvc_request_t *req)
+{
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fxattrop_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fxattrop_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FXATTROP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fxattrop_resume);
+
+ return ret;
+
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+
+int
+server3_3_xattrop (rpcsvc_request_t *req)
+{
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_xattrop_req args = {{0,},};
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_xattrop_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_XATTROP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+ state->dict = dict;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_xattrop_resume);
+
+ return ret;
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ if (dict)
+ dict_unref (dict);
+
+ return ret;
+}
+
+
+int
+server3_3_getxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_getxattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_getxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_GETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen) {
+ state->name = gf_strdup (args.name);
+ /* There can be some commands hidden in key, check and proceed */
+ gf_server_check_getxattr_cmd (frame, state->name);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_getxattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_fgetxattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fgetxattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fgetxattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FGETXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fgetxattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_removexattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_removexattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_removexattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_REMOVEXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_removexattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fremovexattr (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fremovexattr_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (4096);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fremovexattr_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FREMOVEXATTR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->name = gf_strdup (args.name);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fremovexattr_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+
+int
+server3_3_opendir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_opendir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_opendir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_OPENDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_opendir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_readdirp (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readdirp_req args = {{0,},};
+ size_t headers_size = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readdirp_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READDIRP;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ /* FIXME: this should go away when variable sized iobufs are introduced
+ * and transport layer can send msgs bigger than current page-size.
+ */
+ headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
+ if ((frame->this->ctx->page_size < args.size)
+ || ((frame->this->ctx->page_size - args.size) < headers_size)) {
+ state->size = frame->this->ctx->page_size - headers_size;
+ } else {
+ state->size = args.size;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ /* here, dict itself works as xdata */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->dict,
+ (args.dict.dict_val),
+ (args.dict.dict_len), ret,
+ op_errno, out);
+
+
+ ret = 0;
+ resolve_and_resume (frame, server_readdirp_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.dict.dict_val);
+
+ return ret;
+}
+
+int
+server3_3_readdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_readdir_req args = {{0,},};
+ size_t headers_size = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_readdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_READDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ /* FIXME: this should go away when variable sized iobufs are introduced
+ * and transport layer can send msgs bigger than current page-size.
+ */
+ headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
+ if ((frame->this->ctx->page_size < args.size)
+ || ((frame->this->ctx->page_size - args.size) < headers_size)) {
+ state->size = frame->this->ctx->page_size - headers_size;
+ } else {
+ state->size = args.size;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_readdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fsyncdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fsyncdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fsyncdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FSYNCDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = args.fd;
+ state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fsyncdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_mknod (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_mknod_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_mknod_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_MKNOD;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->mode = args.mode;
+ state->dev = args.dev;
+ state->umask = args.umask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_mknod_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ return ret;
+
+}
+
+
+int
+server3_3_mkdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_mkdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_mkdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_MKDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->mode = args.mode;
+ state->umask = args.umask;
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_mkdir_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+int
+server3_3_rmdir (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rmdir_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rmdir_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RMDIR;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+
+ state->flags = args.xflags;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rmdir_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_inodelk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_inodelk_req args = {{0,},};
+ int cmd = 0;
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_inodelk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_INODELK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ cmd = args.cmd;
+ switch (cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = args.type;
+ state->volume = gf_strdup (args.volume);
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_inodelk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_finodelk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_finodelk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_finodelk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FINODELK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->volume = gf_strdup (args.volume);
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = args.type;
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_finodelk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_entrylk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_entrylk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.volume = alloca (256);
+ args.name = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_entrylk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_ENTRYLK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+ state->volume = gf_strdup (args.volume);
+
+ state->cmd = args.cmd;
+ state->type = args.type;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_entrylk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_fentrylk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_fentrylk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.name = alloca (256);
+ args.volume = alloca (256);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_fentrylk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_FENTRYLK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ if (args.namelen)
+ state->name = gf_strdup (args.name);
+ state->volume = gf_strdup (args.volume);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_fentrylk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_access (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_access_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_access_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_ACCESS;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ state->mask = args.mask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_access_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+
+int
+server3_3_symlink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_symlink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.bname = alloca (req->msg[0].iov_len);
+ args.linkname = alloca (4096);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_symlink_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_SYMLINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+ state->name = gf_strdup (args.linkname);
+ state->umask = args.umask;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_symlink_resume);
+
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ return ret;
+}
+
+
+
+int
+server3_3_link (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_link_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.newbname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_LINK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.oldgfid, 16);
+
+ state->resolve2.type = RESOLVE_NOT;
+ state->resolve2.bname = gf_strdup (args.newbname);
+ memcpy (state->resolve2.pargfid, args.newgfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_link_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_rename (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rename_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ args.oldbname = alloca (req->msg[0].iov_len);
+ args.newbname = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rename_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RENAME;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.bname = gf_strdup (args.oldbname);
+ memcpy (state->resolve.pargfid, args.oldgfid, 16);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.bname = gf_strdup (args.newbname);
+ memcpy (state->resolve2.pargfid, args.newgfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rename_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server3_3_lk (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_lk_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_LK;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.fd_no = args.fd;
+ state->cmd = args.cmd;
+ state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ case GF_LK_RESLK_LCK:
+ state->cmd = F_RESLK_LCK;
+ break;
+ case GF_LK_RESLK_LCKW:
+ state->cmd = F_RESLK_LCKW;
+ break;
+ case GF_LK_RESLK_UNLCK:
+ state->cmd = F_RESLK_UNLCK;
+ break;
+ case GF_LK_GETLK_FD:
+ state->cmd = F_GETLK_FD;
+ break;
+
+ }
+
+
+ gf_proto_flock_to_flock (&args.flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ default:
+ gf_log (frame->root->client->bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%s): Unknown lock type: %"PRId32"!",
+ state->resolve.fd_no,
+ uuid_utoa (state->fd->inode->gfid), state->type);
+ break;
+ }
+
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_lk_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ free (args.flock.lk_owner.lk_owner_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+int
+server3_3_rchecksum (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_rchecksum_req args = {0,};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_rchecksum_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_RCHECKSUM;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MAY;
+ state->resolve.fd_no = args.fd;
+ state->offset = args.offset;
+ state->size = args.len;
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_rchecksum_resume);
+out:
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
+server_null (rpcsvc_request_t *req)
+{
+ gf_common_rsp rsp = {0,};
+
+ /* Accepted */
+ rsp.op_ret = 0;
+
+ server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_common_rsp);
+
+ return 0;
+}
+
+int
+server3_3_lookup (rpcsvc_request_t *req)
+{
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+ gfs3_lookup_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ GF_VALIDATE_OR_GOTO ("server", req, err);
+
+ args.bname = alloca (req->msg[0].iov_len);
+ args.xdata.xdata_val = alloca (req->msg[0].iov_len);
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_lookup_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto err;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto err;
+ }
+ frame->root->op = GF_FOP_LOOKUP;
+
+ /* NOTE: lookup() uses req->ino only to identify if a lookup()
+ * is requested for 'root' or not
+ */
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_DONTCARE;
+
+ if (args.bname && strcmp (args.bname, "")) {
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.bname = gf_strdup (args.bname);
+ } else {
+ memcpy (state->resolve.gfid, args.gfid, 16);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_lookup_resume);
+
+ return ret;
+out:
+
+ server_lookup_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
+ NULL, NULL);
+ ret = 0;
+err:
+ return ret;
+}
+
+int
+server3_3_statfs (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_statfs_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = xdr_to_generic (req->msg[0], &args,
+ (xdrproc_t)xdr_gfs3_statfs_req);
+ if (ret < 0) {
+ //failed to decode msg;
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ frame = get_frame_from_request (req);
+ if (!frame) {
+ // something wrong, mostly insufficient memory
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+ frame->root->op = GF_FOP_STATFS;
+
+ state = CALL_STATE (frame);
+ if (!frame->root->client->bound_xl) {
+ /* auth failure, request on subvolume without setvolume */
+ SERVER_REQ_SET_ERROR (req, ret);
+ goto out;
+ }
+
+ state->resolve.type = RESOLVE_MUST;
+ memcpy (state->resolve.gfid, args.gfid, 16);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_statfs_resume);
+out:
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+
+rpcsvc_actor_t glusterfs3_3_fop_actors[] = {
+ [GFS3_OP_NULL] = {"NULL", GFS3_OP_NULL, server_null, NULL, 0, DRC_NA},
+ [GFS3_OP_STAT] = {"STAT", GFS3_OP_STAT, server3_3_stat, NULL, 0, DRC_NA},
+ [GFS3_OP_READLINK] = {"READLINK", GFS3_OP_READLINK, server3_3_readlink, NULL, 0, DRC_NA},
+ [GFS3_OP_MKNOD] = {"MKNOD", GFS3_OP_MKNOD, server3_3_mknod, NULL, 0, DRC_NA},
+ [GFS3_OP_MKDIR] = {"MKDIR", GFS3_OP_MKDIR, server3_3_mkdir, NULL, 0, DRC_NA},
+ [GFS3_OP_UNLINK] = {"UNLINK", GFS3_OP_UNLINK, server3_3_unlink, NULL, 0, DRC_NA},
+ [GFS3_OP_RMDIR] = {"RMDIR", GFS3_OP_RMDIR, server3_3_rmdir, NULL, 0, DRC_NA},
+ [GFS3_OP_SYMLINK] = {"SYMLINK", GFS3_OP_SYMLINK, server3_3_symlink, NULL, 0, DRC_NA},
+ [GFS3_OP_RENAME] = {"RENAME", GFS3_OP_RENAME, server3_3_rename, NULL, 0, DRC_NA},
+ [GFS3_OP_LINK] = {"LINK", GFS3_OP_LINK, server3_3_link, NULL, 0, DRC_NA},
+ [GFS3_OP_TRUNCATE] = {"TRUNCATE", GFS3_OP_TRUNCATE, server3_3_truncate, NULL, 0, DRC_NA},
+ [GFS3_OP_OPEN] = {"OPEN", GFS3_OP_OPEN, server3_3_open, NULL, 0, DRC_NA},
+ [GFS3_OP_READ] = {"READ", GFS3_OP_READ, server3_3_readv, NULL, 0, DRC_NA},
+ [GFS3_OP_WRITE] = {"WRITE", GFS3_OP_WRITE, server3_3_writev, server3_3_writev_vecsizer, 0, DRC_NA},
+ [GFS3_OP_STATFS] = {"STATFS", GFS3_OP_STATFS, server3_3_statfs, NULL, 0, DRC_NA},
+ [GFS3_OP_FLUSH] = {"FLUSH", GFS3_OP_FLUSH, server3_3_flush, NULL, 0, DRC_NA},
+ [GFS3_OP_FSYNC] = {"FSYNC", GFS3_OP_FSYNC, server3_3_fsync, NULL, 0, DRC_NA},
+ [GFS3_OP_SETXATTR] = {"SETXATTR", GFS3_OP_SETXATTR, server3_3_setxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_GETXATTR] = {"GETXATTR", GFS3_OP_GETXATTR, server3_3_getxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_REMOVEXATTR] = {"REMOVEXATTR", GFS3_OP_REMOVEXATTR, server3_3_removexattr, NULL, 0, DRC_NA},
+ [GFS3_OP_OPENDIR] = {"OPENDIR", GFS3_OP_OPENDIR, server3_3_opendir, NULL, 0, DRC_NA},
+ [GFS3_OP_FSYNCDIR] = {"FSYNCDIR", GFS3_OP_FSYNCDIR, server3_3_fsyncdir, NULL, 0, DRC_NA},
+ [GFS3_OP_ACCESS] = {"ACCESS", GFS3_OP_ACCESS, server3_3_access, NULL, 0, DRC_NA},
+ [GFS3_OP_CREATE] = {"CREATE", GFS3_OP_CREATE, server3_3_create, NULL, 0, DRC_NA},
+ [GFS3_OP_FTRUNCATE] = {"FTRUNCATE", GFS3_OP_FTRUNCATE, server3_3_ftruncate, NULL, 0, DRC_NA},
+ [GFS3_OP_FSTAT] = {"FSTAT", GFS3_OP_FSTAT, server3_3_fstat, NULL, 0, DRC_NA},
+ [GFS3_OP_LK] = {"LK", GFS3_OP_LK, server3_3_lk, NULL, 0, DRC_NA},
+ [GFS3_OP_LOOKUP] = {"LOOKUP", GFS3_OP_LOOKUP, server3_3_lookup, NULL, 0, DRC_NA},
+ [GFS3_OP_READDIR] = {"READDIR", GFS3_OP_READDIR, server3_3_readdir, NULL, 0, DRC_NA},
+ [GFS3_OP_INODELK] = {"INODELK", GFS3_OP_INODELK, server3_3_inodelk, NULL, 0, DRC_NA},
+ [GFS3_OP_FINODELK] = {"FINODELK", GFS3_OP_FINODELK, server3_3_finodelk, NULL, 0, DRC_NA},
+ [GFS3_OP_ENTRYLK] = {"ENTRYLK", GFS3_OP_ENTRYLK, server3_3_entrylk, NULL, 0, DRC_NA},
+ [GFS3_OP_FENTRYLK] = {"FENTRYLK", GFS3_OP_FENTRYLK, server3_3_fentrylk, NULL, 0, DRC_NA},
+ [GFS3_OP_XATTROP] = {"XATTROP", GFS3_OP_XATTROP, server3_3_xattrop, NULL, 0, DRC_NA},
+ [GFS3_OP_FXATTROP] = {"FXATTROP", GFS3_OP_FXATTROP, server3_3_fxattrop, NULL, 0, DRC_NA},
+ [GFS3_OP_FGETXATTR] = {"FGETXATTR", GFS3_OP_FGETXATTR, server3_3_fgetxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FSETXATTR] = {"FSETXATTR", GFS3_OP_FSETXATTR, server3_3_fsetxattr, NULL, 0, DRC_NA},
+ [GFS3_OP_RCHECKSUM] = {"RCHECKSUM", GFS3_OP_RCHECKSUM, server3_3_rchecksum, NULL, 0, DRC_NA},
+ [GFS3_OP_SETATTR] = {"SETATTR", GFS3_OP_SETATTR, server3_3_setattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FSETATTR] = {"FSETATTR", GFS3_OP_FSETATTR, server3_3_fsetattr, NULL, 0, DRC_NA},
+ [GFS3_OP_READDIRP] = {"READDIRP", GFS3_OP_READDIRP, server3_3_readdirp, NULL, 0, DRC_NA},
+ [GFS3_OP_RELEASE] = {"RELEASE", GFS3_OP_RELEASE, server3_3_release, NULL, 0, DRC_NA},
+ [GFS3_OP_RELEASEDIR] = {"RELEASEDIR", GFS3_OP_RELEASEDIR, server3_3_releasedir, NULL, 0, DRC_NA},
+ [GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server3_3_fremovexattr, NULL, 0, DRC_NA},
+ [GFS3_OP_FALLOCATE] = {"FALLOCATE", GFS3_OP_FALLOCATE, server3_3_fallocate, NULL, 0, DRC_NA},
+ [GFS3_OP_DISCARD] = {"DISCARD", GFS3_OP_DISCARD, server3_3_discard, NULL, 0, DRC_NA},
+ [GFS3_OP_ZEROFILL] = {"ZEROFILL", GFS3_OP_ZEROFILL, server3_3_zerofill, NULL, 0, DRC_NA},
+};
+
+
+struct rpcsvc_program glusterfs3_3_fop_prog = {
+ .progname = "GlusterFS 3.3",
+ .prognum = GLUSTER_FOP_PROGRAM,
+ .progver = GLUSTER_FOP_VERSION,
+ .numactors = GLUSTER_FOP_PROCCNT,
+ .actors = glusterfs3_3_fop_actors,
+};
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index b0697bb7b..589bd7b36 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -34,7 +25,60 @@
#include "statedump.h"
#include "defaults.h"
#include "authenticate.h"
-#include "rpcsvc.h"
+
+void
+grace_time_handler (void *data)
+{
+ client_t *client = NULL;
+ xlator_t *this = NULL;
+ gf_timer_t *timer = NULL;
+ server_ctx_t *serv_ctx = NULL;
+ gf_boolean_t cancelled = _gf_false;
+ gf_boolean_t detached = _gf_false;
+
+ client = data;
+ this = client->this;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+
+ gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s",
+ client->client_uid);
+
+ serv_ctx = server_ctx_get (client, this);
+
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
+ goto out;
+ }
+
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (serv_ctx->grace_timer) {
+ timer = serv_ctx->grace_timer;
+ serv_ctx->grace_timer = NULL;
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
+ if (timer) {
+ gf_timer_call_cancel (this->ctx, timer);
+ cancelled = _gf_true;
+ }
+ if (cancelled) {
+
+ /*
+ * client must not be destroyed in gf_client_put(),
+ * so take a ref.
+ */
+ gf_client_ref (client);
+ gf_client_put (client, &detached);
+ if (detached)//reconnection did not happen :-(
+ server_connection_cleanup (this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ gf_client_unref (client);
+ }
+out:
+ return;
+}
struct iobuf *
gfs_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg,
@@ -86,8 +130,6 @@ ret:
return iob;
}
-
-
int
server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
@@ -98,16 +140,25 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
struct iovec rsp = {0,};
server_state_t *state = NULL;
char new_iobref = 0;
- server_connection_t *conn = NULL;
+ client_t *client = NULL;
+ gf_boolean_t lk_heal = _gf_false;
+ server_conf_t *conf = NULL;
+ gf_barrier_t *barrier = NULL;
+ gf_barrier_payload_t *stub = NULL;
+ gf_boolean_t barriered = _gf_false;
GF_VALIDATE_OR_GOTO ("server", req, ret);
if (frame) {
state = CALL_STATE (frame);
frame->local = NULL;
- conn = SERVER_CONNECTION(frame);
+ client = frame->root->client;
+ conf = (server_conf_t *) client->this->private;
}
+ if (client)
+ lk_heal = ((server_conf_t *) client->this->private)->lk_heal;
+
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
@@ -125,6 +176,32 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
iobref_add (iobref, iob);
+ if (conf)
+ barrier = conf->barrier;
+ if (barrier) {
+ /* todo: write's with fd flags set to O_SYNC and O_DIRECT */
+ LOCK (&barrier->lock);
+ {
+ if (is_fop_barriered (barrier->fops, req->procnum) &&
+ (barrier_add_to_queue (barrier))) {
+ stub = gf_barrier_payload (req, &rsp, frame,
+ payload,
+ payloadcount, iobref,
+ iob, new_iobref);
+ if (stub) {
+ gf_barrier_enqueue (barrier, stub);
+ barriered = _gf_true;
+ } else {
+ gf_log ("", GF_LOG_ERROR, "Failed to "
+ " barrier fop %"PRIu64,
+ ((uint64_t)1 << req->procnum));
+ }
+ }
+ }
+ UNLOCK (&barrier->lock);
+ if (barriered == _gf_true)
+ goto out;
+ }
/* Then, submit the message for transmission. */
ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
iobref);
@@ -140,8 +217,15 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
iobuf_unref (iob);
if (ret == -1) {
gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed");
- if (frame && conn)
- server_connection_cleanup (frame->this, conn);
+ if (frame && client && !lk_heal) {
+ server_connection_cleanup (frame->this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ } else {
+ gf_log_callingfn ("", GF_LOG_ERROR,
+ "Reply submission failed");
+ /* TODO: Failure of open(dir), create, inodelk, entrylk
+ or lk fops send failure must be handled specially. */
+ }
goto ret;
}
@@ -152,102 +236,17 @@ ret:
}
if (frame) {
+ gf_client_unref (client);
STACK_DESTROY (frame->root);
}
if (new_iobref) {
iobref_unref (iobref);
}
-
- return ret;
-}
-
-/* */
-int
-server_fd_to_dict (xlator_t *this, dict_t *dict)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
- int count = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- conf = this->private;
- if (!conf)
- return -1;
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret)
- return -1;
-
- list_for_each_entry (trav, &conf->conns, list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "conn%d", count++);
- fdtable_dump_to_dict (trav->fdtable, key, dict);
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = dict_set_int32 (dict, "conncount", count);
out:
return ret;
}
-int
-server_fd (xlator_t *this)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("server", this, out);
-
- conf = this->private;
- if (!conf) {
- gf_log (this->name, GF_LOG_WARNING,
- "conf null in xlator");
- return -1;
- }
-
- gf_proc_dump_add_section("xlator.protocol.server.conn");
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump fdtable"
- " errno: %d", errno);
- return -1;
- }
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->id) {
- gf_proc_dump_build_key(key,
- "conn","%d.id", i);
- gf_proc_dump_write(key, "%s", trav->id);
- }
-
- gf_proc_dump_build_key(key,"conn","%d.ref",i)
- gf_proc_dump_write(key, "%d", trav->ref);
- if (trav->bound_xl) {
- gf_proc_dump_build_key(key,
- "conn","%d.bound_xl", i);
- gf_proc_dump_write(key, "%s", trav->bound_xl->name);
- }
-
- gf_proc_dump_build_key(key,
- "conn","%d.id", i);
- fdtable_dump(trav->fdtable,key);
- i++;
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = 0;
-out:
- return ret;
-}
int
server_priv_to_dict (xlator_t *this, dict_t *dict)
@@ -267,28 +266,40 @@ server_priv_to_dict (xlator_t *this, dict_t *dict)
return 0;
//TODO: Dump only specific info to dict
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- peerinfo = &xprt->peerinfo;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.hostname", count);
- ret = dict_set_str (dict, key, peerinfo->identifier);
- if (ret)
- goto out;
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ peerinfo = &xprt->peerinfo;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.hostname",
+ count);
+ ret = dict_set_str (dict, key, peerinfo->identifier);
+ if (ret)
+ goto unlock;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.bytesread", count);
- ret = dict_set_uint64 (dict, key, xprt->total_bytes_read);
- if (ret)
- goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.bytesread",
+ count);
+ ret = dict_set_uint64 (dict, key,
+ xprt->total_bytes_read);
+ if (ret)
+ goto unlock;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.byteswrite", count);
- ret = dict_set_uint64 (dict, key, xprt->total_bytes_write);
- if (ret)
- goto out;
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "client%d.byteswrite",
+ count);
+ ret = dict_set_uint64 (dict, key,
+ xprt->total_bytes_write);
+ if (ret)
+ goto unlock;
- count++;
+ count++;
+ }
}
+unlock:
+ pthread_mutex_unlock (&conf->mutex);
+ if (ret)
+ goto out;
ret = dict_set_int32 (dict, "clientcount", count);
@@ -312,10 +323,19 @@ server_priv (xlator_t *this)
if (!conf)
return 0;
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- total_read += xprt->total_bytes_read;
- total_write += xprt->total_bytes_write;
+ gf_proc_dump_build_key (key, "xlator.protocol.server", "priv");
+ gf_proc_dump_add_section (key);
+
+ ret = pthread_mutex_trylock (&conf->mutex);
+ if (ret != 0)
+ goto out;
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ total_read += xprt->total_bytes_read;
+ total_write += xprt->total_bytes_write;
+ }
}
+ pthread_mutex_unlock (&conf->mutex);
gf_proc_dump_build_key(key, "server", "total-bytes-read");
gf_proc_dump_write(key, "%"PRIu64, total_read);
@@ -325,103 +345,16 @@ server_priv (xlator_t *this)
ret = 0;
out:
- return ret;
-}
-
-int
-server_inode_to_dict (xlator_t *this, dict_t *dict)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[32] = {0,};
- int count = 0;
- int ret = -1;
- xlator_t *prev_bound_xl = NULL;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- conf = this->private;
- if (!conf)
- return -1;
-
- ret = pthread_mutex_trylock (&conf->mutex);
if (ret)
- return -1;
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->bound_xl && trav->bound_xl->itable) {
- /* Presently every brick contains only one
- * bound_xl for all connections. This will lead
- * to duplicating of the inode lists, if listing
- * is done for every connection. This simple check
- * prevents duplication in the present case. If
- * need arises the check can be improved.
- */
- if (trav->bound_xl == prev_bound_xl)
- continue;
- prev_bound_xl = trav->bound_xl;
+ gf_proc_dump_write ("Unable to print priv",
+ "(Lock acquisition failed) %s",
+ this?this->name:"server");
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "conn%d", count);
- inode_table_dump_to_dict (trav->bound_xl->itable,
- key, dict);
- count++;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = dict_set_int32 (dict, "conncount", count);
-
-out:
- if (prev_bound_xl)
- prev_bound_xl = NULL;
return ret;
}
-int
-server_inode (xlator_t *this)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("server", this, out);
-
- conf = this->private;
- if (!conf) {
- gf_log (this->name, GF_LOG_WARNING,
- "conf null in xlator");
- return -1;
- }
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump itable"
- " errno: %d", errno);
- return -1;
- }
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->bound_xl && trav->bound_xl->itable) {
- gf_proc_dump_build_key(key,
- "conn","%d.bound_xl.%s",
- i, trav->bound_xl->name);
- inode_table_dump(trav->bound_xl->itable,key);
- i++;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
- ret = 0;
-out:
- return ret;
-}
-
-
-static void
+static int
get_auth_types (dict_t *this, char *key, data_t *value, void *data)
{
dict_t *auth_dict = NULL;
@@ -458,82 +391,88 @@ get_auth_types (dict_t *this, char *key, data_t *value, void *data)
GF_FREE (key_cpy);
out:
- return;
+ return 0;
}
+int
+_check_for_auth_option (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ int ret = 0;
+ xlator_t *xl = NULL;
+ char *tail = NULL;
+ char *tmp_addr_list = NULL;
+ char *addr = NULL;
+ char *tmp_str = NULL;
+
+ xl = tmp;
+
+ tail = strtail (k, "auth.");
+ if (!tail)
+ goto out;
+
+ /* fast fwd thru module type */
+ tail = strchr (tail, '.');
+ if (!tail)
+ goto out;
+ tail++;
+
+ tail = strtail (tail, xl->name);
+ if (!tail)
+ goto out;
+
+ if (*tail == '.') {
+ /* when we are here, the key is checked for
+ * valid auth.allow.<xlator>
+ * Now we verify the ip address
+ */
+ if (!strcmp (v->data, "*")) {
+ ret = 0;
+ goto out;
+ }
+
+ tmp_addr_list = gf_strdup (v->data);
+ addr = strtok_r (tmp_addr_list, ",", &tmp_str);
+ if (!addr)
+ addr = v->data;
+
+ while (addr) {
+ if (valid_internet_address (addr, _gf_true)) {
+ ret = 0;
+ } else {
+ ret = -1;
+ gf_log (xl->name, GF_LOG_ERROR,
+ "internet address '%s'"
+ " does not conform to"
+ " standards.", addr);
+ goto out;
+ }
+ if (tmp_str)
+ addr = strtok_r (NULL, ",", &tmp_str);
+ else
+ addr = NULL;
+ }
+
+ GF_FREE (tmp_addr_list);
+ tmp_addr_list = NULL;
+ }
+out:
+ return ret;
+}
int
validate_auth_options (xlator_t *this, dict_t *dict)
{
int error = -1;
xlator_list_t *trav = NULL;
- data_pair_t *pair = NULL;
- char *tail = NULL;
- char *addr = NULL;
- char *tmp_str = NULL;
GF_VALIDATE_OR_GOTO ("server", this, out);
GF_VALIDATE_OR_GOTO ("server", dict, out);
trav = this->children;
while (trav) {
- error = -1;
- for (pair = dict->members_list; pair; pair = pair->next) {
- tail = strtail (pair->key, "auth.");
- if (!tail)
- continue;
- /* fast fwd thru module type */
- tail = strchr (tail, '.');
- if (!tail)
- continue;
- tail++;
-
- tail = strtail (tail, trav->xlator->name);
- if (!tail)
- continue;
-
- if (*tail == '.') {
- error = 0;
-
- /* when we are here, the key is checked for
- * valid auth.allow.<xlator>
- * Now we verify the ip address
- */
- if (!strcmp (pair->value->data, "*")) {
- error = 0;
- goto out;
- }
-
- addr = strtok_r (pair->value->data, ",",
- &tmp_str);
- if (!addr)
- addr = pair->value->data;
-
- while (addr) {
-
- if (valid_internet_address (addr) ||
- valid_wildcard_internet_address (addr))
- {
- error = 0;
- } else {
- error = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "internet address '%s'"
- " does not conform to"
- " standards.", addr);
- goto out;
-
- }
- if (tmp_str)
- addr = strtok_r (NULL, ",",
- &tmp_str);
- else
- addr = NULL;
- }
-
- }
-
- }
+ error = dict_foreach (dict, _check_for_auth_option,
+ trav->xlator);
if (-1 == error) {
gf_log (this->name, GF_LOG_ERROR,
@@ -554,11 +493,12 @@ int
server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
void *data)
{
- xlator_t *this = NULL;
- rpc_transport_t *xprt = NULL;
- server_connection_t *conn = NULL;
- server_conf_t *conf = NULL;
-
+ gf_boolean_t detached = _gf_false;
+ xlator_t *this = NULL;
+ rpc_transport_t *trans = NULL;
+ server_conf_t *conf = NULL;
+ client_t *client = NULL;
+ server_ctx_t *serv_ctx = NULL;
if (!xl || !data) {
gf_log_callingfn ("server", GF_LOG_WARNING,
@@ -567,7 +507,7 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
}
this = xl;
- xprt = data;
+ trans = data;
conf = this->private;
switch (event) {
@@ -575,34 +515,85 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
{
/* Have a structure per new connection */
/* TODO: Should we create anything here at all ? * /
- conn = create_server_conn_state (this, xprt);
- if (!conn)
+ client->conn = create_server_conn_state (this, trans);
+ if (!client->conn)
goto out;
- xprt->protocol_private = conn;
+ trans->protocol_private = client->conn;
*/
- INIT_LIST_HEAD (&xprt->list);
+ INIT_LIST_HEAD (&trans->list);
- list_add_tail (&xprt->list, &conf->xprt_list);
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_add_tail (&trans->list, &conf->xprt_list);
+ }
+ pthread_mutex_unlock (&conf->mutex);
break;
}
case RPCSVC_EVENT_DISCONNECT:
- conn = get_server_conn_state (this, xprt);
- if (conn)
- server_connection_cleanup (this, conn);
+ /* transport has to be removed from the list upon disconnect
+ * irrespective of whether lock self heal is off or on, since
+ * new transport will be created upon reconnect.
+ */
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_del_init (&trans->list);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ client = trans->xl_private;
+ if (!client)
+ break;
+
+ gf_log (this->name, GF_LOG_INFO, "disconnecting connection"
+ "from %s", client->client_uid);
+
+ /* If lock self heal is off, then destroy the
+ conn object, else register a grace timer event */
+ if (!conf->lk_heal) {
+ gf_client_ref (client);
+ gf_client_put (client, &detached);
+ if (detached)
+ server_connection_cleanup (this, client,
+ INTERNAL_LOCKS | POSIX_LOCKS);
+ gf_client_unref (client);
+ break;
+ }
+ trans->xl_private = NULL;
+ server_connection_cleanup (this, client, INTERNAL_LOCKS);
- gf_log (this->name, GF_LOG_INFO,
- "disconnected connection from %s",
- xprt->peerinfo.identifier);
+ serv_ctx = server_ctx_get (client, this);
- list_del (&xprt->list);
+ if (serv_ctx == NULL) {
+ gf_log (this->name, GF_LOG_INFO,
+ "server_ctx_get() failed");
+ goto out;
+ }
+ LOCK (&serv_ctx->fdtable_lock);
+ {
+ if (!serv_ctx->grace_timer) {
+
+ gf_log (this->name, GF_LOG_INFO,
+ "starting a grace timer for %s",
+ client->client_uid);
+
+ serv_ctx->grace_timer =
+ gf_timer_call_after (this->ctx,
+ conf->grace_ts,
+ grace_time_handler,
+ client);
+ }
+ }
+ UNLOCK (&serv_ctx->fdtable_lock);
break;
case RPCSVC_EVENT_TRANSPORT_DESTROY:
- conn = get_server_conn_state (this, xprt);
- if (conn)
- server_connection_put (this, conn);
+ /*- conn obj has been disassociated from trans on first
+ * disconnect.
+ * conn cleanup and destruction is handed over to
+ * grace_time_handler or the subsequent handler that 'owns'
+ * the conn. Nothing left to be done here. */
break;
default:
break;
@@ -631,43 +622,82 @@ out:
}
-static void
-_delete_auth_opt (dict_t *this,
- char *key,
- data_t *value,
- void *data)
+static int
+_delete_auth_opt (dict_t *this, char *key, data_t *value, void *data)
{
char *auth_option_pattern[] = { "auth.addr.*.allow",
- "auth.addr.*.reject"};
- if (fnmatch ( auth_option_pattern[0], key, 0) != 0) {
- dict_del (this, key);
- return;
- }
+ "auth.addr.*.reject",
+ NULL};
+ int i = 0;
- if (fnmatch ( auth_option_pattern[1], key, 0) != 0) {
- dict_del (this, key);
- return;
+ for (i = 0; auth_option_pattern[i]; i++) {
+ if (fnmatch (auth_option_pattern[i], key, 0) == 0) {
+ dict_del (this, key);
+ break;
+ }
}
+
+ return 0;
}
-static void
-_copy_auth_opt (dict_t *unused,
- char *key,
- data_t *value,
- void *xl_dict)
+static int
+_copy_auth_opt (dict_t *unused, char *key, data_t *value, void *xl_dict)
{
char *auth_option_pattern[] = { "auth.addr.*.allow",
- "auth.addr.*.reject"};
- if (fnmatch ( auth_option_pattern[0], key, 0) != 0)
- dict_set ((dict_t *)xl_dict, key, (value));
+ "auth.addr.*.reject",
+ NULL};
+ int i = 0;
+
+ for (i = 0; auth_option_pattern [i]; i++) {
+ if (fnmatch (auth_option_pattern[i], key, 0) == 0) {
+ dict_set ((dict_t *)xl_dict, key, value);
+ break;
+ }
+ }
- if (fnmatch ( auth_option_pattern[1], key, 0) != 0)
- dict_set ((dict_t *)xl_dict, key, (value));
+ return 0;
}
int
+server_init_grace_timer (xlator_t *this, dict_t *options,
+ server_conf_t *conf)
+{
+ int32_t ret = -1;
+ int32_t grace_timeout = -1;
+ char *lk_heal = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, options, out);
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ conf->lk_heal = _gf_false;
+
+ ret = dict_get_str (options, "lk-heal", &lk_heal);
+ if (!ret)
+ gf_string2boolean (lk_heal, &conf->lk_heal);
+
+ gf_log (this->name, GF_LOG_DEBUG, "lk-heal = %s",
+ (conf->lk_heal) ? "on" : "off");
+
+ ret = dict_get_int32 (options, "grace-timeout", &grace_timeout);
+ if (!ret)
+ conf->grace_ts.tv_sec = grace_timeout;
+ else
+ conf->grace_ts.tv_sec = 10;
+
+ gf_log (this->name, GF_LOG_DEBUG, "Server grace timeout "
+ "value = %"PRIu64, conf->grace_ts.tv_sec);
+
+ conf->grace_ts.tv_nsec = 0;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
reconfigure (xlator_t *this, dict_t *options)
{
@@ -698,22 +728,15 @@ reconfigure (xlator_t *this, dict_t *options)
gf_log (this->name, GF_LOG_WARNING,
"'trace' takes on only boolean values. "
"Neglecting option");
- ret = -1;
+ ret = -1;
goto out;
- }
- conf->trace = trace;
- gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace"
- " to %d", conf->trace);
+ }
+ conf->trace = trace;
+ gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace"
+ " to %d", conf->trace);
- }
+ }
- /*ret = dict_get_str (options, "statedump-path", &statedump_path);
- if (!ret) {
- gf_path_strip_trailing_slashes (statedump_path);
- if (this->ctx->statedump_path)
- GF_FREE (this->ctx->statedump_path);
- this->ctx->statedump_path = gf_strdup (statedump_path);
- }*/
GF_OPTION_RECONF ("statedump-path", statedump_path,
options, path, out);
if (!statedump_path) {
@@ -723,8 +746,7 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
}
gf_path_strip_trailing_slashes (statedump_path);
- if (this->ctx->statedump_path)
- GF_FREE (this->ctx->statedump_path);
+ GF_FREE (this->ctx->statedump_path);
this->ctx->statedump_path = gf_strdup (statedump_path);
if (!conf->auth_modules)
@@ -752,6 +774,8 @@ reconfigure (xlator_t *this, dict_t *options)
}
(void) rpcsvc_set_allow_insecure (rpc_conf, options);
+ (void) rpcsvc_set_root_squash (rpc_conf, options);
+ (void) rpcsvc_set_outstanding_rpc_limit (rpc_conf, options);
list_for_each_entry (listeners, &(rpc_conf->listeners), list) {
if (listeners->trans != NULL) {
if (listeners->trans->reconfigure )
@@ -761,12 +785,33 @@ reconfigure (xlator_t *this, dict_t *options)
"Reconfigure not found for transport" );
}
}
+ ret = server_init_grace_timer (this, options, conf);
out:
gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
return ret;
}
+static int32_t
+client_destroy_cbk (xlator_t *this, client_t *client)
+{
+ void *tmp = NULL;
+ server_ctx_t *ctx = NULL;
+
+ client_ctx_del (client, this, &tmp);
+
+ ctx = tmp;
+
+ if (ctx == NULL)
+ return 0;
+
+ gf_fd_fdtable_destroy (ctx->fdtable);
+ LOCK_DESTROY (&ctx->fdtable_lock);
+ GF_FREE (ctx);
+
+ return 0;
+}
+
int
init (xlator_t *this)
{
@@ -774,6 +819,8 @@ init (xlator_t *this)
server_conf_t *conf = NULL;
rpcsvc_listener_t *listener = NULL;
char *statedump_path = NULL;
+ gf_barrier_t *barrier = NULL;
+ char *str = NULL;
GF_VALIDATE_OR_GOTO ("init", this, out);
if (this->children == NULL) {
@@ -793,10 +840,13 @@ init (xlator_t *this)
GF_VALIDATE_OR_GOTO(this->name, conf, out);
- INIT_LIST_HEAD (&conf->conns);
INIT_LIST_HEAD (&conf->xprt_list);
pthread_mutex_init (&conf->mutex, NULL);
+ ret = server_init_grace_timer (this, this->options, conf);
+ if (ret)
+ goto out;
+
ret = server_build_config (this, conf);
if (ret)
goto out;
@@ -839,8 +889,7 @@ init (xlator_t *this)
}
/* RPC related */
- //conf->rpc = rpc_svc_init (&conf->rpc_conf);
- conf->rpc = rpcsvc_init (this, this->ctx, this->options);
+ conf->rpc = rpcsvc_init (this, this->ctx, this->options, 0);
if (conf->rpc == NULL) {
gf_log (this->name, GF_LOG_WARNING,
"creation of rpcsvc failed");
@@ -864,14 +913,14 @@ init (xlator_t *this)
goto out;
}
- glusterfs3_1_fop_prog.options = this->options;
- ret = rpcsvc_program_register (conf->rpc, &glusterfs3_1_fop_prog);
+ glusterfs3_3_fop_prog.options = this->options;
+ ret = rpcsvc_program_register (conf->rpc, &glusterfs3_3_fop_prog);
if (ret) {
gf_log (this->name, GF_LOG_WARNING,
"registration of program (name:%s, prognum:%d, "
- "progver:%d) failed", glusterfs3_1_fop_prog.progname,
- glusterfs3_1_fop_prog.prognum,
- glusterfs3_1_fop_prog.progver);
+ "progver:%d) failed", glusterfs3_3_fop_prog.progname,
+ glusterfs3_3_fop_prog.prognum,
+ glusterfs3_3_fop_prog.progver);
goto out;
}
@@ -883,7 +932,7 @@ init (xlator_t *this)
"progver:%d) failed", gluster_handshake_prog.progname,
gluster_handshake_prog.prognum,
gluster_handshake_prog.progver);
- rpcsvc_program_unregister (conf->rpc, &glusterfs3_1_fop_prog);
+ rpcsvc_program_unregister (conf->rpc, &glusterfs3_3_fop_prog);
goto out;
}
@@ -912,6 +961,37 @@ init (xlator_t *this)
}
}
#endif
+ /* barrier related */
+ barrier = GF_CALLOC (1, sizeof (*barrier),1);
+ if (!barrier) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "WARNING: Failed to allocate barrier");
+ ret = -1;
+ goto out;
+ }
+
+ LOCK_INIT (&barrier->lock);
+ INIT_LIST_HEAD (&barrier->queue);
+ barrier->on = _gf_false;
+
+ GF_OPTION_INIT ("barrier-queue-length", barrier->max_size,
+ int64, out);
+ GF_OPTION_INIT ("barrier-timeout", barrier->time_out,
+ uint64, out);
+
+ ret = dict_get_str (this->options, "barrier-fops", &str);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting barrier fops to default value");
+ }
+ ret = gf_barrier_fops_configure (this, barrier, str);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid barrier fops specified");
+ goto out;
+ }
+
+ conf->barrier = barrier;
this->private = conf;
ret = 0;
@@ -965,29 +1045,65 @@ int
notify (xlator_t *this, int32_t event, void *data, ...)
{
int ret = 0;
+ int32_t val = 0;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ va_list ap;
+
+ dict = data;
+ va_start (ap, data);
+ output = va_arg (ap, dict_t*);
+ va_end (ap);
+
switch (event) {
+ case GF_EVENT_VOLUME_BARRIER_OP:
+ ret = dict_get_int32 (dict, "barrier", &val);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Wrong BARRIER event");
+ goto out;
+ }
+ /* !val un-barrier, if val, barrier */
+ if (val) {
+ ret = gf_barrier_start (this);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Barrier start failed");
+ } else {
+ ret = gf_barrier_stop (this);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Barrier stop failed");
+ }
+ ret = dict_set_int32 (output, "barrier-status", ret);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set barrier-status in dict");
+ break;
+
+ /* todo: call default_notify to make other xlators handle it.*/
default:
default_notify (this, event, data);
break;
}
-
+out:
return ret;
}
-struct xlator_fops fops = {
-};
+struct xlator_fops fops;
struct xlator_cbks cbks = {
+ .client_destroy = client_destroy_cbk,
};
struct xlator_dumpops dumpops = {
.priv = server_priv,
- .fd = server_fd,
- .inode = server_inode,
+ .fd = gf_client_dump_fdtables,
+ .inode = gf_client_dump_inodes,
.priv_to_dict = server_priv_to_dict,
- .fd_to_dict = server_fd_to_dict,
- .inode_to_dict = server_inode_to_dict,
+ .fd_to_dict = gf_client_dump_fdtables_to_dict,
+ .inode_to_dict = gf_client_dump_inodes_to_dict,
};
@@ -1013,7 +1129,10 @@ struct volume_options options[] = {
{ .key = {"inode-lru-limit"},
.type = GF_OPTION_TYPE_INT,
.min = 0,
- .max = (1 * GF_UNIT_MB)
+ .max = (1 * GF_UNIT_MB),
+ .default_value = "16384",
+ .description = "Specifies the maximum megabytes of memory to be "
+ "used in the inode cache."
},
{ .key = {"verify-volfile-checksum"},
.type = GF_OPTION_TYPE_BOOL
@@ -1028,9 +1147,68 @@ struct volume_options options[] = {
{ .key = {"rpc-auth-allow-insecure"},
.type = GF_OPTION_TYPE_BOOL,
},
+ { .key = {"root-squash"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "Map requests from uid/gid 0 to the anonymous "
+ "uid/gid. Note that this does not apply to any other"
+ "uids or gids that might be equally sensitive, such as"
+ "user bin or group staff."
+ },
{ .key = {"statedump-path"},
.type = GF_OPTION_TYPE_PATH,
- .default_value = "/tmp"
+ .default_value = DEFAULT_VAR_RUN_DIRECTORY,
+ .description = "Specifies directory in which gluster should save its"
+ " statedumps. By default it is the /tmp directory"
+ },
+ { .key = {"lk-heal"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ },
+ {.key = {"grace-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 10,
+ .max = 1800,
+ },
+ {.key = {"tcp-window-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = GF_MIN_SOCKET_WINDOW_SIZE,
+ .max = GF_MAX_SOCKET_WINDOW_SIZE,
+ .description = "Specifies the window size for tcp socket."
+ },
+
+ /* The following two options are defined in addr.c, redifined here *
+ * for the sake of validation during volume set from cli */
+
+ { .key = {"auth.addr.*.allow"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .description = "Allow a comma separated list of addresses and/or "
+ "hostnames to connect to the server. By default, all"
+ " connections are allowed."
+ },
+ { .key = {"auth.addr.*.reject"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .description = "Reject a comma separated list of addresses and/or "
+ "hostnames to connect to the server. By default, all"
+ " connections are allowed."
+ },
+ {.key = {"barrier-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "60",
+ .min = 0,
+ .max = 360,
+ .description = "Barrier timeout in seconds",
+ },
+ {.key = {"barrier-queue-length"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "4096",
+ .min = 0,
+ .max = 16384,
+ .description = "Barrier queue length",
+ },
+ {.key = {"barrier-fops"},
+ .type = GF_OPTION_TYPE_STR,
+ .description = "Allow a comma seperated fop lists",
},
{ .key = {NULL} },
};
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index 92785c5a9..782327d77 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _SERVER_H
@@ -22,59 +13,55 @@
#include <pthread.h>
+#include "fd.h"
#include "rpcsvc.h"
#include "fd.h"
#include "protocol-common.h"
#include "server-mem-types.h"
#include "glusterfs3.h"
+#include "timer.h"
+#include "client_t.h"
#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
-
-typedef struct _server_state server_state_t;
-
-struct _locker {
- struct list_head lockers;
- char *volume;
- loc_t loc;
- fd_t *fd;
- gf_lkowner_t owner;
- pid_t pid;
+#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
+#define GF_MIN_SOCKET_WINDOW_SIZE (0)
+
+struct _gf_barrier_payload {
+ rpcsvc_request_t *req;
+ struct iovec rsp;
+ call_frame_t *frame;
+ struct iovec *payload;
+ struct iobref *iobref;
+ struct iobuf *iob;
+ int payload_count;
+ gf_boolean_t free_iobref;
+ struct list_head list;
};
-struct _lock_table {
- struct list_head inodelk_lockers;
- struct list_head entrylk_lockers;
- gf_lock_t lock;
- size_t count;
+typedef struct _gf_barrier_payload gf_barrier_payload_t;
+
+struct _gf_barrier {
+ gf_lock_t lock;
+ gf_boolean_t on;
+ gf_boolean_t force;
+ size_t cur_size;
+ int64_t max_size;
+ uint64_t fops;
+ gf_timer_t *timer;
+ uint64_t time_out;
+ struct list_head queue;
};
-/* private structure per connection (transport object)
- * used as transport_t->xl_private
- */
-struct _server_connection {
- struct list_head list;
- char *id;
- int ref;
- pthread_mutex_t lock;
- fdtable_t *fdtable;
- struct _lock_table *ltable;
- xlator_t *bound_xl;
- xlator_t *this;
-};
-
-typedef struct _server_connection server_connection_t;
-
+typedef struct _gf_barrier gf_barrier_t;
-server_connection_t *
-server_connection_get (xlator_t *this, const char *id);
-
-void
-server_connection_put (xlator_t *this, server_connection_t *conn);
+typedef enum {
+ INTERNAL_LOCKS = 1,
+ POSIX_LOCKS = 2,
+} server_lock_flags_t;
-int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn);
+typedef struct _server_state server_state_t;
int server_null (rpcsvc_request_t *req);
@@ -90,13 +77,16 @@ struct server_conf {
int inode_lru_limit;
gf_boolean_t verify_volfile;
gf_boolean_t trace;
+ gf_boolean_t lk_heal; /* If true means lock self
+ heal is on else off. */
char *conf_dir;
struct _volfile_ctx *volfile;
-
+ struct timespec grace_ts;
dict_t *auth_modules;
pthread_mutex_t mutex;
- struct list_head conns;
+ gf_barrier_t *barrier;
struct list_head xprt_list;
+ pthread_t barrier_th;
};
typedef struct server_conf server_conf_t;
@@ -117,7 +107,7 @@ struct resolve_comp {
typedef struct {
server_resolve_type_t type;
- uint64_t fd_no;
+ int64_t fd_no;
u_char gfid[16];
u_char pargfid[16];
char *path;
@@ -134,11 +124,10 @@ int
resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn);
struct _server_state {
- server_connection_t *conn;
- rpc_transport_t *xprt;
- inode_table_t *itable;
+ rpc_transport_t *xprt;
+ inode_table_t *itable;
- server_resume_fn_t resume_fn;
+ server_resume_fn_t resume_fn;
loc_t loc;
loc_t loc2;
@@ -174,15 +163,28 @@ struct _server_state {
int mask;
char is_revalidate;
dict_t *dict;
- struct gf_flock flock;
+ struct gf_flock flock;
const char *volume;
dir_entry_t *entry;
+
+ dict_t *xdata;
+ mode_t umask;
};
+
extern struct rpcsvc_program gluster_handshake_prog;
-extern struct rpcsvc_program glusterfs3_1_fop_prog;
+extern struct rpcsvc_program glusterfs3_3_fop_prog;
extern struct rpcsvc_program gluster_ping_prog;
+
+typedef struct _server_ctx {
+ gf_lock_t fdtable_lock;
+ fdtable_t *fdtable;
+ struct _gf_timer *grace_timer;
+ uint32_t lk_version;
+} server_ctx_t;
+
+
int
server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c
deleted file mode 100644
index 3dae07b03..000000000
--- a/xlators/protocol/server/src/server3_1-fops.c
+++ /dev/null
@@ -1,5007 +0,0 @@
-/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "server.h"
-#include "server-helpers.h"
-#include "glusterfs3-xdr.h"
-#include "glusterfs3.h"
-#include "compat-errno.h"
-
-#include "md5.h"
-#include "xdr-nfs3.h"
-
-
-/* Callback function section */
-int
-server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf)
-{
- gfs3_statfs_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret >= 0) {
- gf_statfs_from_statfs (&rsp.statfs, buf);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": STATFS %"PRId32" (%s)",
- frame->root->unique, op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_statfs_rsp);
-
- return 0;
-}
-
-int
-server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *dict,
- struct iatt *postparent)
-{
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
- inode_t *root_inode = NULL;
- inode_t *link_inode = NULL;
- loc_t fresh_loc = {0,};
- gfs3_lookup_rsp rsp = {0,};
- uuid_t rootgfid = {0,};
-
- state = CALL_STATE(frame);
-
- req = frame->local;
-
- if (state->is_revalidate == 1 && op_ret == -1) {
- state->is_revalidate = 2;
- loc_copy (&fresh_loc, &state->loc);
- inode_unref (fresh_loc.inode);
- fresh_loc.inode = inode_new (state->itable);
-
- STACK_WIND (frame, server_lookup_cbk, BOUND_XL (frame),
- BOUND_XL (frame)->fops->lookup,
- &fresh_loc, state->dict);
-
- loc_wipe (&fresh_loc);
- return 0;
- }
-
- if ((op_ret >= 0) && dict) {
- GF_PROTOCOL_DICT_SERIALIZE (this, dict,
- (&rsp.dict.dict_val),
- rsp.dict.dict_len,
- op_errno, out);
- }
-
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- if (op_ret == 0) {
- root_inode = BOUND_XL(frame)->itable->root;
- if (inode == root_inode) {
- /* we just looked up root ("/") */
- stbuf->ia_ino = 1;
- rootgfid[15] = 1;
- uuid_copy (stbuf->ia_gfid, rootgfid);
- if (inode->ia_type == 0)
- inode->ia_type = stbuf->ia_type;
- }
-
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
- if (!__is_root_gfid (inode->gfid)) {
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
- }
- } else {
- if (state->is_revalidate && op_errno == ENOENT) {
- if (!__is_root_gfid (state->loc.inode->gfid)) {
- inode_unlink (state->loc.inode,
- state->loc.parent,
- state->loc.name);
- }
- }
- }
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret) {
- gf_log (this->name,
- ((op_errno == ENOENT) ? GF_LOG_TRACE : GF_LOG_INFO),
- "%"PRId64": LOOKUP %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
-
- if (rsp.dict.dict_val)
- GF_FREE (rsp.dict.dict_val);
-
- return 0;
-}
-
-
-int
-server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
-{
- gfs3_lk_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- switch (lock->l_type) {
- case F_RDLCK:
- lock->l_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- lock->l_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- lock->l_type = GF_LK_F_UNLCK;
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "Unknown lock type: %"PRId32"!", lock->l_type);
- break;
- }
-
- gf_proto_flock_from_flock (&rsp.flock, lock);
- } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": LK %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lk_rsp);
-
- return 0;
-}
-
-
-int
-server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, &frame->root->lk_owner,
- GF_FOP_INODELK);
- else
- gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid,
- &frame->root->lk_owner,
- GF_FOP_INODELK);
- } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": INODELK %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-
-int
-server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- server_connection_t *conn = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn->ltable, state->volume,
- NULL, state->fd,
- &frame->root->lk_owner, GF_FOP_INODELK);
- else
- gf_add_locker (conn->ltable, state->volume,
- NULL, state->fd,
- frame->root->pid,
- &frame->root->lk_owner, GF_FOP_INODELK);
- } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FINODELK %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- gf_common_rsp rsp = {0,};
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- if (op_ret >= 0) {
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn->ltable, state->volume,
- &state->loc, NULL, &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
- else
- gf_add_locker (conn->ltable, state->volume,
- &state->loc, NULL, frame->root->pid,
- &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
- } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": ENTRYLK %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
- return 0;
-}
-
-
-int
-server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
- if (op_ret >= 0) {
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn->ltable, state->volume,
- NULL, state->fd, &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
- else
- gf_add_locker (conn->ltable, state->volume,
- NULL, state->fd, frame->root->pid,
- &frame->root->lk_owner, GF_FOP_ENTRYLK);
- } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FENTRYLK %"PRId64" (%s) "
- " ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-
-int
-server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
-
- state = CALL_STATE(frame);
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": ACCESS %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_rmdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *parent = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
- parent = inode_parent (state->loc.inode, 0, NULL);
- if (parent)
- inode_unref (parent);
- else
- inode_forget (state->loc.inode, 0);
-
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RMDIR %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rmdir_rsp);
-
- return 0;
-}
-
-int
-server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_mkdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
- if (op_ret >= 0) {
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKDIR %s ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_mkdir_rsp);
-
- return 0;
-}
-
-int
-server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_mknod_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
- if (op_ret >= 0) {
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKNOD %s ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_mknod_rsp);
-
-
- return 0;
-}
-
-int
-server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
-{
- gfs3_readdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- int ret = 0;
-
- req = frame->local;
-
- state = CALL_STATE(frame);
- if (op_ret > 0) {
- ret = serialize_rsp_dirent (entries, &rsp);
- if (ret == -1) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
- } else {
- /* (op_ret == 0) is valid, and means EOF, don't log for that */
- gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE,
- "%"PRId64": READDIR %"PRId64" (%s) ==> %"PRId32
- " (%s)", frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-unwind:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readdir_rsp);
-
- readdir_rsp_cleanup (&rsp);
-
- return 0;
-}
-
-
-int
-server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
-{
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- gfs3_opendir_rsp rsp = {0,};
- uint64_t fd_no = 0;
-
- conn = SERVER_CONNECTION (frame);
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- fd_bind (fd);
-
- fd_no = gf_fd_unused_get (conn->fdtable, fd);
- fd_ref (fd); // on behalf of the client
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": OPENDIR %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- req = frame->local;
-
- rsp.fd = fd_no;
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_opendir_rsp);
-
- return 0;
-}
-
-int
-server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
- state = CALL_STATE(frame);
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": REMOVEXATTR %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
- state = CALL_STATE(frame);
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FREMOVEXATTR (%s) ==> %"PRId32" (%s)",
- frame->root->unique, ((state->fd->inode) ?
- uuid_utoa (state->fd->inode->gfid) :
- "--"),
- op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gfs3_getxattr_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- GF_PROTOCOL_DICT_SERIALIZE (this, dict,
- (&rsp.dict.dict_val),
- rsp.dict.dict_len,
- op_errno, out);
- }
-out:
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": GETXATTR %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->name, op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_getxattr_rsp);
-
- if (rsp.dict.dict_val)
- GF_FREE (rsp.dict.dict_val);
-
- return 0;
-}
-
-
-int
-server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- gfs3_fgetxattr_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- state = CALL_STATE (frame);
-
- if (op_ret >= 0) {
- GF_PROTOCOL_DICT_SERIALIZE (this, dict,
- (&rsp.dict.dict_val),
- rsp.dict.dict_len,
- op_errno, out);
- }
-
-out:
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FGETXATTR %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->name, op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
-
- if (rsp.dict.dict_val)
- GF_FREE (rsp.dict.dict_val);
-
- return 0;
-}
-
-int
-server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
-
- state = CALL_STATE(frame);
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SETXATTR %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-
-int
-server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- req = frame->local;
-
- state = CALL_STATE(frame);
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- return 0;
-}
-
-int
-server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent)
-{
- gfs3_rename_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- stbuf->ia_type = state->loc.inode->ia_type;
-
- /* TODO: log gfid of the inodes */
- gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RENAME_CBK %s ==> %s",
- frame->root->unique, state->loc.name, state->loc2.name);
-
- inode_rename (state->itable,
- state->loc.parent, state->loc.name,
- state->loc2.parent, state->loc2.name,
- state->loc.inode, stbuf);
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
- gf_stat_from_iatt (&rsp.preoldparent, preoldparent);
- gf_stat_from_iatt (&rsp.postoldparent, postoldparent);
-
- gf_stat_from_iatt (&rsp.prenewparent, prenewparent);
- gf_stat_from_iatt (&rsp.postnewparent, postnewparent);
- }
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RENAME %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rename_rsp);
-
- return 0;
-}
-
-int
-server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_unlink_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *parent = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- /* TODO: log gfid of the inodes */
- gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": UNLINK_CBK %s",
- frame->root->unique, state->loc.name);
-
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
-
- parent = inode_parent (state->loc.inode, 0, NULL);
- if (parent)
- inode_unref (parent);
- else
- inode_forget (state->loc.inode, 0);
-
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": UNLINK %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_unlink_rsp);
-
- return 0;
-}
-
-int
-server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_symlink_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
- if (op_ret >= 0) {
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SYMLINK %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_symlink_rsp);
-
- return 0;
-}
-
-
-int
-server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent)
-{
- gfs3_link_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
-
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc2.parent,
- state->loc2.name, stbuf);
- inode_unref (link_inode);
- }
-
- if (op_ret == -1)
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": LINK %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_link_rsp);
-
- return 0;
-}
-
-int
-server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
-{
- gfs3_truncate_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE (frame);
-
- if (op_ret == 0) {
- gf_stat_from_iatt (&rsp.prestat, prebuf);
- gf_stat_from_iatt (&rsp.poststat, postbuf);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": TRUNCATE %s (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) :
- "--", op_ret, strerror (op_errno));
- }
-
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_truncate_rsp);
-
- return 0;
-}
-
-int
-server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
-{
- gfs3_fstat_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- req = frame->local;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- state = CALL_STATE(frame);
-
- if (op_ret == 0) {
- gf_stat_from_iatt (&rsp.stat, stbuf);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSTAT %"PRId64" (%s) ==> %"PRId32" (%s)",
- frame->root->unique, state->resolve.fd_no,
- state->fd ? uuid_utoa (state->fd->inode->gfid) : "--",
- op_ret, strerror (op_errno));
- }
-