diff options
| author | Vikas Gorur <vikas@zresearch.com> | 2009-03-03 16:00:58 +0530 | 
|---|---|---|
| committer | Anand V. Avati <avati@amp.gluster.com> | 2009-03-07 02:08:41 +0530 | 
| commit | 0991858fca6dc93de685e9527fb9ff47d77f616f (patch) | |
| tree | adcdf627d40c1fe90a8535c7b0bc27d057901788 | |
| parent | d092dff9a6e23d5fdef64154b6f3d6211f7482a6 (diff) | |
added fgetxattr and fsetxattr FOPs
Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
| -rw-r--r-- | libglusterfs/src/call-stub.c | 184 | ||||
| -rw-r--r-- | libglusterfs/src/call-stub.h | 50 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.c | 12 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.c | 73 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.h | 11 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 20 | ||||
| -rw-r--r-- | libglusterfs/src/protocol.h | 23 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 2 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 28 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-protocol.c | 170 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-protocol.c | 204 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 223 | 
12 files changed, 977 insertions, 23 deletions
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index c1288d905..92301a2dd 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -1537,6 +1537,105 @@ out:  	return stub;  } + +call_stub_t * +fop_fsetxattr_stub (call_frame_t *frame, +                    fop_fsetxattr_t fn, +                    fd_t *fd, +                    dict_t *dict, +                    int32_t flags) +{ +	call_stub_t *stub = NULL; + +	GF_VALIDATE_OR_GOTO ("call-stub", frame, out); +	GF_VALIDATE_OR_GOTO ("call-stub", fd, out); + +	stub = stub_new (frame, 1, GF_FOP_FSETXATTR); +	GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +	stub->args.fsetxattr.fn = fn; +	stub->args.fsetxattr.fd = fd_ref (fd); + +	/* TODO */ +	if (dict) +		stub->args.fsetxattr.dict = dict_ref (dict); +	stub->args.fsetxattr.flags = flags; +out: +	return stub; +} + + +call_stub_t * +fop_fsetxattr_cbk_stub (call_frame_t *frame, +                        fop_fsetxattr_cbk_t fn, +                        int32_t op_ret, +                        int32_t op_errno) +{ +	call_stub_t *stub = NULL; + +	GF_VALIDATE_OR_GOTO ("call-stub", frame, out); + +	stub = stub_new (frame, 0, GF_FOP_FSETXATTR); +	GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +	stub->args.fsetxattr_cbk.fn = fn; +	stub->args.fsetxattr_cbk.op_ret = op_ret; +	stub->args.fsetxattr_cbk.op_errno = op_errno; +out: +	return stub; +} + + +call_stub_t * +fop_fgetxattr_stub (call_frame_t *frame, +                    fop_fgetxattr_t fn, +                    fd_t *fd, +                    const char *name) +{ +	call_stub_t *stub = NULL; + +	GF_VALIDATE_OR_GOTO ("call-stub", frame, out); +	GF_VALIDATE_OR_GOTO ("call-stub", fd, out); + +	stub = stub_new (frame, 1, GF_FOP_FGETXATTR); +	GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +	stub->args.fgetxattr.fn = fn; +	stub->args.fgetxattr.fd = fd_ref (fd); + +	if (name) +	        stub->args.fgetxattr.name = strdup (name); +out: +	return stub; +} + + +call_stub_t * +fop_fgetxattr_cbk_stub (call_frame_t *frame, +                        fop_fgetxattr_cbk_t fn, +                        int32_t op_ret, +                        int32_t op_errno, +                        dict_t *dict) +{ +	call_stub_t *stub = NULL; + +	GF_VALIDATE_OR_GOTO ("call-stub", frame, out); + +	stub = stub_new (frame, 0, GF_FOP_GETXATTR); +	GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +	stub->args.fgetxattr_cbk.fn = fn; +	stub->args.fgetxattr_cbk.op_ret = op_ret; +	stub->args.fgetxattr_cbk.op_errno = op_errno; + +	/* TODO */ +	if (dict) +		stub->args.fgetxattr_cbk.dict = dict_ref (dict); +out: +	return stub; +} + +  call_stub_t *  fop_removexattr_stub (call_frame_t *frame,  		      fop_removexattr_t fn, @@ -2340,6 +2439,25 @@ call_resume_wind (call_stub_t *stub)  		break;  	} +	case GF_FOP_FSETXATTR: +	{ +		stub->args.fsetxattr.fn (stub->frame, +                                         stub->frame->this, +                                         stub->args.fsetxattr.fd, +                                         stub->args.fsetxattr.dict, +                                         stub->args.fsetxattr.flags); +		break; +	} + +	case GF_FOP_FGETXATTR: +	{ +		stub->args.fgetxattr.fn (stub->frame, +                                         stub->frame->this, +                                         stub->args.fgetxattr.fd, +                                         stub->args.fgetxattr.name); +		break; +	} +  	case GF_FOP_REMOVEXATTR:  	{  		stub->args.removexattr.fn (stub->frame, @@ -2953,7 +3071,41 @@ call_resume_unwind (call_stub_t *stub)  						    stub->args.getxattr_cbk.dict);  		break;  	} -   + +	case GF_FOP_FSETXATTR: +	{ +		if (!stub->args.fsetxattr_cbk.fn) +			STACK_UNWIND (stub->frame, +				      stub->args.fsetxattr_cbk.op_ret, +				      stub->args.fsetxattr_cbk.op_errno); + +		else +			stub->args.fsetxattr_cbk.fn (stub->frame, +                                                     stub->frame->cookie, +                                                     stub->frame->this, +                                                     stub->args.fsetxattr_cbk.op_ret, +                                                     stub->args.fsetxattr_cbk.op_errno); + +		break; +	} + +	case GF_FOP_FGETXATTR: +	{ +		if (!stub->args.fgetxattr_cbk.fn) +			STACK_UNWIND (stub->frame, +				      stub->args.fgetxattr_cbk.op_ret, +				      stub->args.fgetxattr_cbk.op_errno, +				      stub->args.fgetxattr_cbk.dict); +		else +			stub->args.fgetxattr_cbk.fn (stub->frame, +                                                     stub->frame->cookie, +                                                     stub->frame->this, +                                                     stub->args.fgetxattr_cbk.op_ret, +                                                     stub->args.fgetxattr_cbk.op_errno, +                                                     stub->args.fgetxattr_cbk.dict); +		break; +	} +  	case GF_FOP_REMOVEXATTR:  	{  		if (!stub->args.removexattr_cbk.fn) @@ -3518,13 +3670,29 @@ call_stub_destroy_wind (call_stub_t *stub)  		break;  	} +	case GF_FOP_FSETXATTR: +	{ +		fd_unref (stub->args.fsetxattr.fd); +		if (stub->args.fsetxattr.dict) +			dict_unref (stub->args.fsetxattr.dict); +		break; +	} + +	case GF_FOP_FGETXATTR: +	{ +		if (stub->args.fgetxattr.name) +			FREE (stub->args.fgetxattr.name); +		fd_unref (stub->args.fgetxattr.fd); +		break; +	} +  	case GF_FOP_REMOVEXATTR:  	{  		loc_wipe (&stub->args.removexattr.loc);  		FREE (stub->args.removexattr.name);  		break;  	} -   +  	case GF_FOP_OPENDIR:  	{  		loc_wipe (&stub->args.opendir.loc); @@ -3805,9 +3973,19 @@ call_stub_destroy_unwind (call_stub_t *stub)  	}  	break; +	case GF_FOP_FSETXATTR: +		break; + +	case GF_FOP_FGETXATTR: +	{ +		if (stub->args.fgetxattr_cbk.dict) +			dict_unref (stub->args.fgetxattr_cbk.dict); +	} +	break; +  	case GF_FOP_REMOVEXATTR:  		break; -   +  	case GF_FOP_OPENDIR:  	{  		if (stub->args.opendir_cbk.fd) diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h index ee2ba98a0..d80ddd173 100644 --- a/libglusterfs/src/call-stub.h +++ b/libglusterfs/src/call-stub.h @@ -436,6 +436,30 @@ typedef struct {  			dict_t *dict;  		} getxattr_cbk; +		/* fsetxattr */ +		struct { +			fop_fsetxattr_t fn; +			fd_t *fd; +			dict_t *dict; +			int32_t flags; +		} fsetxattr; +		struct { +			fop_fsetxattr_cbk_t fn; +			int32_t op_ret, op_errno; +		} fsetxattr_cbk; + +		/* fgetxattr */ +		struct { +			fop_fgetxattr_t fn; +			fd_t *fd; +			const char *name; +		} fgetxattr; +		struct { +			fop_fgetxattr_cbk_t fn; +			int32_t op_ret, op_errno; +			dict_t *dict; +		} fgetxattr_cbk; +  		/* removexattr */  		struct {  			fop_removexattr_t fn; @@ -1010,6 +1034,32 @@ fop_getxattr_cbk_stub (call_frame_t *frame,  		       dict_t *value);  call_stub_t * +fop_fsetxattr_stub (call_frame_t *frame, +                    fop_fsetxattr_t fn, +                    fd_t *fd, +                    dict_t *dict, +                    int32_t flags); + +call_stub_t * +fop_fsetxattr_cbk_stub (call_frame_t *frame, +                        fop_fsetxattr_cbk_t fn, +                        int32_t op_ret, +                        int32_t op_errno); + +call_stub_t * +fop_fgetxattr_stub (call_frame_t *frame, +                    fop_fgetxattr_t fn, +                    fd_t *fd, +                    const char *name); + +call_stub_t * +fop_fgetxattr_cbk_stub (call_frame_t *frame, +                        fop_fgetxattr_cbk_t fn, +                        int32_t op_ret, +                        int32_t op_errno, +                        dict_t *value); + +call_stub_t *  fop_removexattr_stub (call_frame_t *frame,  		      fop_removexattr_t fn,  		      loc_t *loc, diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index e8a7c9ab5..372195daa 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -202,30 +202,32 @@ gf_global_variable_init()  	gf_fop_list[GF_FOP_SETDENTS]    = "SETDENTS";   /* 35 */  	gf_fop_list[GF_FOP_READDIR]     = "READDIR";  	gf_fop_list[GF_FOP_INODELK]     = "INODELK"; -	gf_fop_list[GF_FOP_FINODELK]    = "FINODELK";       +	gf_fop_list[GF_FOP_FINODELK]    = "FINODELK";  	gf_fop_list[GF_FOP_ENTRYLK]     = "ENTRYLK";  	gf_fop_list[GF_FOP_FENTRYLK]    = "FENTRYLK";   /* 40 */ -	gf_fop_list[GF_FOP_CHECKSUM]    = "CHECKSUM";   /* 41 */    +	gf_fop_list[GF_FOP_CHECKSUM]    = "CHECKSUM";   /* 41 */  	gf_fop_list[GF_FOP_XATTROP]     = "XATTROP";  	gf_fop_list[GF_FOP_LOCK_NOTIFY] = "LOCK_NOTIFY";  	gf_fop_list[GF_FOP_LOCK_FNOTIFY]= "LOCK_FNOTIFY"; +	gf_fop_list[GF_FOP_FSETXATTR]   = "FSETXATTR"; +	gf_fop_list[GF_FOP_FGETXATTR]   = "FGETXATTR";  	gf_mop_list[GF_MOP_SETVOLUME]   = "SETVOLUME"; /* 0 */  	gf_mop_list[GF_MOP_GETVOLUME]   = "GETVOLUME"; /* 1 */  	gf_mop_list[GF_MOP_STATS]       = "STATS";  	gf_mop_list[GF_MOP_SETSPEC]     = "SETSPEC";  	gf_mop_list[GF_MOP_GETSPEC]     = "GETSPEC"; -	 +  	gf_cbk_list[GF_CBK_FORGET]      = "FORGET";  	gf_cbk_list[GF_CBK_RELEASE]     = "RELEASE";  	gf_cbk_list[GF_CBK_RELEASEDIR]  = "RELEASEDIR"; -	/* Are there any more variables to be included? All global  +	/* Are there any more variables to be included? All global  	   variables initialization should go here */  	return;  } -void  +void  set_global_ctx_ptr (glusterfs_ctx_t *ctx)  {  	gf_global_ctx = ctx; diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c index 69d03160e..dc2908633 100644 --- a/libglusterfs/src/defaults.c +++ b/libglusterfs/src/defaults.c @@ -974,13 +974,76 @@ default_setxattr (call_frame_t *frame,  	return 0;  } + +static int32_t +default_fsetxattr_cbk (call_frame_t *frame, +                       void *cookie, +                       xlator_t *this, +                       int32_t op_ret, +                       int32_t op_errno) +{ +	STACK_UNWIND (frame, +		      op_ret, +		      op_errno); +	return 0; +} + +int32_t +default_fsetxattr (call_frame_t *frame, +                   xlator_t *this, +                   fd_t *fd, +                   dict_t *dict, +                   int32_t flags) +{ +	STACK_WIND (frame, +		    default_fsetxattr_cbk, +		    FIRST_CHILD(this), +		    FIRST_CHILD(this)->fops->fsetxattr, +		    fd, +		    dict, +		    flags); +	return 0; +} + + +static int32_t +default_fgetxattr_cbk (call_frame_t *frame, +                       void *cookie, +                       xlator_t *this, +                       int32_t op_ret, +                       int32_t op_errno, +                       dict_t *dict) +{ +	STACK_UNWIND (frame, +		      op_ret, +		      op_errno, +		      dict); +	return 0; +} + + +int32_t +default_fgetxattr (call_frame_t *frame, +                   xlator_t *this, +                   fd_t *fd, +                   const char *name) +{ +	STACK_WIND (frame, +		    default_fgetxattr_cbk, +		    FIRST_CHILD(this), +		    FIRST_CHILD(this)->fops->fgetxattr, +		    fd, +		    name); +	return 0; +} +  static int32_t  default_getxattr_cbk (call_frame_t *frame, -		      void *cookie, -		      xlator_t *this, -		      int32_t op_ret, -		      int32_t op_errno, -		      dict_t *dict) +                      void *cookie, +                      xlator_t *this, +                      int32_t op_ret, +                      int32_t op_errno, +                      dict_t *dict)  {  	STACK_UNWIND (frame,  		      op_ret, diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index 22c814b7d..615222300 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -207,6 +207,17 @@ int32_t default_getxattr (call_frame_t *frame,  			  loc_t *loc,  			  const char *name); +int32_t default_fsetxattr (call_frame_t *frame, +                           xlator_t *this, +                           fd_t *fd, +                           dict_t *dict, +                           int32_t flags); + +int32_t default_fgetxattr (call_frame_t *frame, +                           xlator_t *this, +                           fd_t *fd, +                           const char *name); +  int32_t default_removexattr (call_frame_t *frame,  			     xlator_t *this,  			     loc_t *loc, diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index d00ec4866..b828a3ecd 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -101,32 +101,34 @@ typedef enum {          GF_FOP_FLUSH,          GF_FOP_FSYNC,          GF_FOP_SETXATTR, -        GF_FOP_GETXATTR,    +        GF_FOP_GETXATTR,          GF_FOP_REMOVEXATTR,/* 20 */          GF_FOP_OPENDIR,          GF_FOP_GETDENTS, -        GF_FOP_FSYNCDIR,    +        GF_FOP_FSYNCDIR,          GF_FOP_ACCESS,          GF_FOP_CREATE,     /* 25 */          GF_FOP_FTRUNCATE,          GF_FOP_FSTAT, -        GF_FOP_LK,          +        GF_FOP_LK,          GF_FOP_UTIMENS,          GF_FOP_FCHMOD,     /* 30 */          GF_FOP_FCHOWN,          GF_FOP_LOOKUP,          GF_FOP_SETDENTS, -        GF_FOP_READDIR,     +        GF_FOP_READDIR,          GF_FOP_INODELK,   /* 35 */ -        GF_FOP_FINODELK,  -	GF_FOP_ENTRYLK,   -	GF_FOP_FENTRYLK,   -        GF_FOP_CHECKSUM,       +        GF_FOP_FINODELK, +	GF_FOP_ENTRYLK, +	GF_FOP_FENTRYLK, +        GF_FOP_CHECKSUM,          GF_FOP_XATTROP,  /* 40 */          GF_FOP_FXATTROP,          GF_FOP_LOCK_NOTIFY,          GF_FOP_LOCK_FNOTIFY, -        GF_FOP_MAXVALUE,   +        GF_FOP_FGETXATTR, +        GF_FOP_FSETXATTR, +        GF_FOP_MAXVALUE,  } glusterfs_fop_t;  /* NOTE: add members ONLY at the end (just before _MAXVALUE) */ diff --git a/libglusterfs/src/protocol.h b/libglusterfs/src/protocol.h index 82e42cfb1..35f172ab7 100644 --- a/libglusterfs/src/protocol.h +++ b/libglusterfs/src/protocol.h @@ -397,6 +397,17 @@ typedef struct {  } __attribute__((packed)) gf_fop_setxattr_req_t;  typedef struct { } __attribute__((packed)) gf_fop_setxattr_rsp_t; + +typedef struct { +        uint64_t ino; +	int64_t  fd; +	uint32_t flags; +	uint32_t dict_len; +	char     dict[0]; +} __attribute__((packed)) gf_fop_fsetxattr_req_t; +typedef struct { } __attribute__((packed)) gf_fop_fsetxattr_rsp_t; + +  typedef struct {  	uint64_t ino;  	uint32_t flags; @@ -438,6 +449,18 @@ typedef struct {  typedef struct { +        uint64_t ino; +	int64_t  fd; +        uint32_t namelen; +	char     name[0]; +} __attribute__((packed)) gf_fop_fgetxattr_req_t; +typedef struct { +	uint32_t dict_len; +	char     dict[0]; +} __attribute__((packed)) gf_fop_fgetxattr_rsp_t; + + +typedef struct {  	uint64_t ino;  	char     path[0];  	char     name[0]; diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 2706609af..090fbc727 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -75,6 +75,8 @@ fill_defaults (xlator_t *xl)  	SET_DEFAULT_FOP (fsync);  	SET_DEFAULT_FOP (setxattr);  	SET_DEFAULT_FOP (getxattr); +	SET_DEFAULT_FOP (fsetxattr); +	SET_DEFAULT_FOP (fgetxattr);  	SET_DEFAULT_FOP (removexattr);  	SET_DEFAULT_FOP (opendir);  	SET_DEFAULT_FOP (readdir); diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index d353a663f..a5a20e8b2 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -352,6 +352,19 @@ typedef int32_t (*fop_getxattr_cbk_t) (call_frame_t *frame,  				       int32_t op_errno,  				       dict_t *dict); +typedef int32_t (*fop_fsetxattr_cbk_t) (call_frame_t *frame, +                                        void *cookie, +                                        xlator_t *this, +                                        int32_t op_ret, +                                        int32_t op_errno); + +typedef int32_t (*fop_fgetxattr_cbk_t) (call_frame_t *frame, +                                        void *cookie, +                                        xlator_t *this, +                                        int32_t op_ret, +                                        int32_t op_errno, +                                        dict_t *dict); +  typedef int32_t (*fop_removexattr_cbk_t) (call_frame_t *frame,  					  void *cookie,  					  xlator_t *this, @@ -589,6 +602,17 @@ typedef int32_t (*fop_getxattr_t) (call_frame_t *frame,  				   loc_t *loc,  				   const char *name); +typedef int32_t (*fop_fsetxattr_t) (call_frame_t *frame, +                                    xlator_t *this, +                                    fd_t *fd, +                                    dict_t *dict, +                                    int32_t flags); + +typedef int32_t (*fop_fgetxattr_t) (call_frame_t *frame, +                                    xlator_t *this, +                                    fd_t *fd, +                                    const char *name); +  typedef int32_t (*fop_removexattr_t) (call_frame_t *frame,  				      xlator_t *this,  				      loc_t *loc, @@ -687,6 +711,8 @@ struct xlator_fops {  	fop_statfs_t         statfs;  	fop_setxattr_t       setxattr;  	fop_getxattr_t       getxattr; +	fop_fsetxattr_t      fsetxattr; +	fop_fgetxattr_t      fgetxattr;  	fop_removexattr_t    removexattr;  	fop_lk_t             lk;  	fop_inodelk_t        inodelk; @@ -733,6 +759,8 @@ struct xlator_fops {  	fop_statfs_cbk_t         statfs_cbk;  	fop_setxattr_cbk_t       setxattr_cbk;  	fop_getxattr_cbk_t       getxattr_cbk; +	fop_fsetxattr_cbk_t      fsetxattr_cbk; +	fop_fgetxattr_cbk_t      fgetxattr_cbk;  	fop_removexattr_cbk_t    removexattr_cbk;  	fop_lk_cbk_t             lk_cbk;  	fop_inodelk_cbk_t        inodelk_cbk; diff --git a/xlators/protocol/client/src/client-protocol.c b/xlators/protocol/client/src/client-protocol.c index bcc98d0f1..2a636a18f 100644 --- a/xlators/protocol/client/src/client-protocol.c +++ b/xlators/protocol/client/src/client-protocol.c @@ -2350,6 +2350,97 @@ unwind:  	return 0;  } + +/** + * client_fsetxattr - fsetxattr function for client protocol + * @frame: call frame + * @this: this translator structure + * @fd: fd + * @dict: dictionary which contains key:value to be set. + * @flags: + * + * external reference through client_protocol_xlator->fops->fsetxattr + */ +int32_t +client_fsetxattr (call_frame_t *frame, +                  xlator_t *this, +                  fd_t *fd, +                  dict_t *dict, +                  int32_t flags) +{ +	gf_hdr_common_t       *hdr = NULL; +	gf_fop_fsetxattr_req_t *req = NULL; +	size_t hdrlen = 0; +	size_t dict_len = 0; +        ino_t  ino; +	int    ret = -1; +	int64_t remote_fd = -1; +	client_conf_t *conf = this->private; + +	if (conf->child) { +		/* */ +		STACK_WIND (frame, +			    default_fsetxattr_cbk, +			    conf->child, +			    conf->child->fops->fsetxattr, +			    fd, +			    dict, +			    flags); + +		return 0; +	} + +	dict_len = dict_serialized_length (dict); +	if (dict_len < 0) { +		gf_log (this->name, GF_LOG_ERROR, +			"failed to get serialized length of dict(%p)", +			dict); +		goto unwind; +	} + +        ret = this_fd_get (fd, this, &remote_fd); +        if (ret == -1) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "(%"PRId64"): failed to get remote fd. returning EBADFD", +                        fd->inode->ino); +                goto unwind; +        } +        ino = fd->inode->ino; + +	hdrlen = gf_hdr_len (req, dict_len); +	hdr    = gf_hdr_new (req, dict_len); + +	GF_VALIDATE_OR_GOTO(this->name, hdr, unwind); + +	req    = gf_param (hdr); + +	req->ino   = hton64 (ino); +        req->fd    = hton64 (remote_fd); +	req->flags = hton32 (flags); +	req->dict_len = hton32 (dict_len); + +	ret = dict_serialize (dict, req->dict); +	if (ret < 0) { +		gf_log (this->name, GF_LOG_ERROR, +			"failed to serialize dictionary(%p)", +			dict); +		goto unwind; +	} + +	ret = protocol_client_xfer (frame, this, +				    CLIENT_CHANNEL (this, CHANNEL_BULK), +				    GF_OP_TYPE_FOP_REQUEST, GF_FOP_FSETXATTR, +				    hdr, hdrlen, NULL, 0, NULL); +	return ret; +unwind: +	if (hdr) +		free (hdr); + +	STACK_UNWIND(frame, -1, EINVAL); +	return 0; +} + +  /**   * client_getxattr - getxattr function for client protocol   * @frame: call frame @@ -2416,6 +2507,83 @@ unwind:  	return 0;  } + +/** + * client_fgetxattr - fgetxattr function for client protocol + * @frame: call frame + * @this: this translator structure + * @fd: fd + * + * external reference through client_protocol_xlator->fops->fgetxattr + */ + +int32_t +client_fgetxattr (call_frame_t *frame, +                  xlator_t *this, +                  fd_t *fd, +                  const char *name) +{ +	int ret = -1; +	gf_hdr_common_t *hdr = NULL; +	gf_fop_fgetxattr_req_t *req = NULL; +	size_t hdrlen = 0; +        int64_t remote_fd = -1; +	size_t namelen = 0; +	ino_t  ino = 0; +	client_conf_t *conf = this->private; + +	if (conf->child) { +		/* */ +		STACK_WIND (frame, +			    default_fgetxattr_cbk, +			    conf->child, +			    conf->child->fops->fgetxattr, +			    fd, +			    name); + +		return 0; +	} + +	if (name) +		namelen = STRLEN_0(name); + +        ret = this_fd_get (fd, this, &remote_fd); +        if (ret == -1) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "(%"PRId64"): failed to get remote fd. returning EBADFD", +                        fd->inode->ino); +                goto unwind; +        } +        ino = fd->inode->ino; + +	hdrlen = gf_hdr_len (req, namelen); +	hdr    = gf_hdr_new (req, namelen); + +	GF_VALIDATE_OR_GOTO(frame->this->name, hdr, unwind); + +	req    = gf_param (hdr); + +	req->ino   = hton64 (ino); +        req->fd    = hton64 (remote_fd); +	req->namelen = hton32 (namelen); + +	if (name) +		strcpy (req->name, name); + +	ret = protocol_client_xfer (frame, this, +				    CLIENT_CHANNEL (this, CHANNEL_LOWLAT), +				    GF_OP_TYPE_FOP_REQUEST, GF_FOP_FGETXATTR, +				    hdr, hdrlen, NULL, 0, NULL); +	return ret; +unwind: +	if (hdr) +		free (hdr); + +	STACK_UNWIND(frame, -1, EINVAL, NULL); +	return 0; +} + +  /**   * client_removexattr - removexattr function for client protocol   * @frame: call frame @@ -6703,6 +6871,8 @@ struct xlator_fops fops = {  	.fsync       = client_fsync,  	.setxattr    = client_setxattr,  	.getxattr    = client_getxattr, +        .fsetxattr   = client_fsetxattr, +        .fgetxattr   = client_fgetxattr,  	.removexattr = client_removexattr,  	.opendir     = client_opendir,  	.readdir     = client_readdir, diff --git a/xlators/protocol/server/src/server-protocol.c b/xlators/protocol/server/src/server-protocol.c index 4e06aaa5e..0a3e3e011 100644 --- a/xlators/protocol/server/src/server-protocol.c +++ b/xlators/protocol/server/src/server-protocol.c @@ -1339,6 +1339,67 @@ server_getxattr_cbk (call_frame_t *frame,  	return 0;  } + +int32_t +server_fgetxattr_cbk (call_frame_t *frame, +                      void *cookie, +                      xlator_t *this, +                      int32_t op_ret, +                      int32_t op_errno, +                      dict_t *dict) +{ +	gf_hdr_common_t       *hdr  = NULL; +	gf_fop_fgetxattr_rsp_t *rsp = NULL; +	server_state_t *state = NULL; +	size_t  hdrlen = 0; +	int32_t len = 0; +	int32_t gf_errno = 0; +	int32_t ret = -1; + +	state = CALL_STATE(frame); + +	if (op_ret >= 0) { +		len = dict_serialized_length (dict); +		if (len < 0) { +			gf_log (this->name, GF_LOG_ERROR, +				"%s (%"PRId64"): failed to get serialized length of " +				"reply dict", +				state->loc.path, state->ino); +			op_ret   = -1; +			op_errno = EINVAL; +			len = 0; +		} +	} + +	hdrlen = gf_hdr_len (rsp, len + 1); +	hdr    = gf_hdr_new (rsp, len + 1); +	rsp    = gf_param (hdr); + +	if (op_ret >= 0) { +		ret = dict_serialize (dict, rsp->dict); +		if (len < 0) { +			gf_log (this->name, GF_LOG_ERROR, +				"%s (%"PRId64"): failed to serialize reply dict", +				state->loc.path, state->ino); +			op_ret = -1; +			op_errno = -ret; +		} +	} +	rsp->dict_len = hton32 (len); + +	hdr->rsp.op_ret = hton32 (op_ret); +	gf_errno        = gf_errno_to_error (op_errno); +	hdr->rsp.op_errno = hton32 (gf_errno); + +	fd_unref (state->fd); + +	protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FGETXATTR, +			       hdr, hdrlen, NULL, 0, NULL); + +	return 0; +} + +  /*   * server_setxattr_cbk - setxattr callback for server protocol   * @frame: call frame @@ -1380,6 +1441,35 @@ server_setxattr_cbk (call_frame_t *frame,  } +int32_t +server_fsetxattr_cbk (call_frame_t *frame, +                      void *cookie, +                      xlator_t *this, +                      int32_t op_ret, +                      int32_t op_errno) +{ +	gf_hdr_common_t        *hdr = NULL; +	gf_fop_fsetxattr_rsp_t *rsp = NULL; +	server_state_t *state = NULL; +	size_t  hdrlen = 0; +	int32_t gf_errno = 0; +	state = CALL_STATE(frame); + +	hdrlen = gf_hdr_len (rsp, 0); +	hdr    = gf_hdr_new (rsp, 0); +	rsp    = gf_param (hdr); + +	hdr->rsp.op_ret = hton32 (op_ret); +	gf_errno        = gf_errno_to_error (op_errno); +	hdr->rsp.op_errno = hton32 (gf_errno); + +	protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_FSETXATTR, +			       hdr, hdrlen, NULL, 0, NULL); + +	return 0; +} + +  /*   * server_rename_cbk - rename callback for server protocol   * @frame: call frame @@ -4696,10 +4786,82 @@ fail:  	server_setxattr_cbk (frame, NULL, frame->this,  			     -1, ENOENT);  	return 0; -	 +  } +int32_t +server_fsetxattr (call_frame_t *frame, +                  xlator_t *bound_xl, +                  gf_hdr_common_t *hdr, size_t hdrlen, +                  char *buf, size_t buflen) +{ +        server_connection_t *conn   = NULL; +	gf_fop_fsetxattr_req_t *req = NULL; + +	dict_t *dict = NULL; +	server_state_t *state = NULL; +	int32_t ret = -1; +	size_t pathlen = 0; +	size_t dict_len = 0; +	char *req_dictbuf = NULL; + +        conn = SERVER_CONNECTION (frame); + +	req = gf_param (hdr); +	state = CALL_STATE(frame); +	{ +                state->fd_no = ntoh64 (req->fd); +                if (state->fd_no >= 0) +                        state->fd = gf_fd_fdptr_get (conn->fdtable, +                                                     state->fd_no); +		dict_len = ntoh32 (req->dict_len); + +		pathlen = STRLEN_0(state->path); +		state->ino   = ntoh64 (req->ino); + +		state->flags = ntoh32 (req->flags); +	} + +        /* Unserialize the dictionary */ +        req_dictbuf = memdup (req->dict, dict_len); +        GF_VALIDATE_OR_GOTO(bound_xl->name, req_dictbuf, fail); + +        dict = dict_new (); +        GF_VALIDATE_OR_GOTO(bound_xl->name, dict, fail); +         +        ret = dict_unserialize (req_dictbuf, dict_len, &dict); +        if (ret < 0) { +                gf_log (bound_xl->name, GF_LOG_ERROR, +                        "%"PRId64": %s (%"PRId64"): failed to " +                        "unserialize request buffer to dictionary", +                        frame->root->unique, state->loc.path, +                        state->ino); +                free (req_dictbuf); +                goto fail; +        } else{ +                dict->extra_free = req_dictbuf; +        } + +        STACK_WIND (frame,  +                    server_setxattr_cbk, +                    BOUND_XL(frame), +                    BOUND_XL(frame)->fops->fsetxattr, +                    state->fd, dict, state->flags); + +	if (dict) +		dict_unref (dict); + +        return 0; +fail: +	if (dict) +		dict_unref (dict); + +	server_fsetxattr_cbk (frame, NULL, frame->this, +                              -1, ENOENT); +	return 0; +} +  int32_t  server_fxattrop (call_frame_t *frame, @@ -4950,6 +5112,44 @@ server_getxattr (call_frame_t *frame,  } +int32_t +server_fgetxattr (call_frame_t *frame, +                  xlator_t *bound_xl, +                  gf_hdr_common_t *hdr, size_t hdrlen, +                  char *buf, size_t buflen) +{ +        server_connection_t    *conn = NULL; +	gf_fop_fgetxattr_req_t *req  = NULL; +	server_state_t *state        = NULL; + +	size_t namelen = 0; + +        conn = SERVER_CONNECTION (frame); + +	req   = gf_param (hdr); +	state = CALL_STATE(frame); +	{ +                state->fd_no   = ntoh64 (req->fd); +                if (state->fd_no >= 0) +                        state->fd = gf_fd_fdptr_get (conn->fdtable, +                                                     state->fd_no); + +		state->ino     = ntoh64 (req->ino); + +		namelen = ntoh32 (req->namelen); +		if (namelen) +			state->name = (req->name); +	} + +	STACK_WIND (frame, +		    server_fgetxattr_cbk, +		    BOUND_XL(frame), +		    BOUND_XL(frame)->fops->fgetxattr, +		    state->fd, +		    state->name); +	return 0; +} +  int32_t  server_removexattr_resume (call_frame_t *frame, @@ -7640,6 +7840,8 @@ static gf_op_t gf_fops[] = {  	[GF_FOP_FSYNC]        =  server_fsync,  	[GF_FOP_SETXATTR]     =  server_setxattr,  	[GF_FOP_GETXATTR]     =  server_getxattr, +        [GF_FOP_FGETXATTR]    =  server_fgetxattr, +        [GF_FOP_FSETXATTR]    =  server_fsetxattr,  	[GF_FOP_REMOVEXATTR]  =  server_removexattr,  	[GF_FOP_OPENDIR]      =  server_opendir,  	[GF_FOP_GETDENTS]     =  server_getdents, diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index bbcdc93de..9ee6ed510 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -2279,6 +2279,227 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,          return 0;  } + +int32_t +posix_fgetxattr (call_frame_t *frame, xlator_t *this, +                 fd_t *fd, const char *name) +{ +        int32_t           op_ret         = -1; +        int32_t           op_errno       = ENOENT; +        uint64_t          tmp_pfd        = 0; +        struct posix_fd * pfd            = NULL; +        int               _fd            = -1; +        int32_t           list_offset    = 0; +        size_t            size           = 0; +        size_t            remaining_size = 0; +        char              key[1024]      = {0,}; +        char *            value          = NULL; +        char *            list           = NULL; +        dict_t *          dict           = NULL; +        int               ret            = -1; + +        DECLARE_OLD_FS_ID_VAR; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); + +        SET_FS_ID (frame->root->uid, frame->root->gid); + +        ret = fd_ctx_get (fd, this, &tmp_pfd); +        if (ret < 0) { +                op_errno = -ret; +                gf_log (this->name, GF_LOG_ERROR, +			"pfd is NULL from fd=%p", fd); +                goto out; +        } +	pfd = (struct posix_fd *)(long)tmp_pfd; + +        _fd = pfd->fd; + +        /* Get the total size */ +        dict = get_new_dict (); +        if (!dict) { +                gf_log (this->name, GF_LOG_ERROR, "out of memory :("); +                goto out; +        } + +        size = flistxattr (_fd, NULL, 0); +        if (size == -1) { +                op_errno = errno; +                if ((errno == ENOTSUP) || (errno == ENOSYS)) { +                        GF_LOG_OCCASIONALLY (gf_posix_xattr_enotsup_log, +                                             this->name, GF_LOG_WARNING, +                                             "Extended attributes not " +					     "supported."); +                } +                else { +                        gf_log (this->name, GF_LOG_ERROR, +				"listxattr failed on %p: %s", +                                fd, strerror (op_errno)); +                } +                goto out; +        } + +        if (size == 0) +                goto done; + +        list = alloca (size + 1); +        if (!list) { +                op_errno = errno; +                gf_log (this->name, GF_LOG_ERROR, "out of memory :("); +                goto out; +        } + +        size = flistxattr (_fd, list, size); + +        remaining_size = size; +        list_offset = 0; +        while (remaining_size > 0) { +                if(*(list + list_offset) == '\0') +                        break; + +                strcpy (key, list + list_offset); +                op_ret = fgetxattr (_fd, key, NULL, 0); +                if (op_ret == -1) +                        break; + +                value = CALLOC (op_ret + 1, sizeof(char)); +                if (!value) { +                        op_errno = errno; +                        gf_log (this->name, GF_LOG_ERROR, "out of memory :("); +                        goto out; +                } + +                op_ret = fgetxattr (_fd, key, value, op_ret); +                if (op_ret == -1) +                        break; + +                value [op_ret] = '\0'; +                dict_set (dict, key, data_from_dynptr (value, op_ret)); +                remaining_size -= strlen (key) + 1; +                list_offset += strlen (key) + 1; + +        } /* while (remaining_size > 0) */ + + done: +        op_ret = size; + +        if (dict) { +                dict_ref (dict); +        } + + out: +        SET_TO_OLD_FS_ID (); +        frame->root->rsp_refs = NULL; +        STACK_UNWIND (frame, op_ret, op_errno, dict); + +        if (dict) +                dict_unref (dict); + +        return 0; +} + + +int +fhandle_pair (xlator_t *this, int fd, +              data_pair_t *trav, int flags) +{ +        int sys_ret = -1; +        int ret     = 0; + +        sys_ret = fsetxattr (fd, trav->key, trav->value->data, +                             trav->value->len, flags); +         +        if (sys_ret < 0) { +                if (errno == ENOTSUP) { +                        GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log, +                                            this->name,GF_LOG_WARNING, +                                            "Extended attributes not " +                                            "supported"); +                } else if (errno == ENOENT) { +                        gf_log (this->name, GF_LOG_DEBUG, +                                "fsetxattr on fd=%d failed: %s", fd, +                                strerror (errno)); +                } else { +                         +#ifdef GF_DARWIN_HOST_OS +                        gf_log (this->name, +                                ((errno == EINVAL) ? +                                 GF_LOG_DEBUG : GF_LOG_WARNING), +                                "fd=%d: key:%s error:%s", +                                fd, trav->key, +                                strerror (errno)); +#else /* ! DARWIN */ +                        gf_log (this->name, GF_LOG_WARNING, +                                "fd=%d: key:%s error:%s", +                                fd, trav->key, +                                strerror (errno)); +#endif /* DARWIN */ +                } +                 +                ret = -errno; +                goto out; +        } + +out: +        return ret; +} + + +int32_t +posix_fsetxattr (call_frame_t *frame, xlator_t *this, +                 fd_t *fd, dict_t *dict, int flags) +{ +        int32_t            op_ret       = -1; +        int32_t            op_errno     = 0; +        struct posix_fd *  pfd          = NULL; +        uint64_t           tmp_pfd      = 0; +        int                _fd          = -1; +        data_pair_t * trav              = NULL; +        int           ret               = -1; + +        DECLARE_OLD_FS_ID_VAR; +        SET_FS_ID (frame->root->uid, frame->root->gid); + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); +        VALIDATE_OR_GOTO (dict, out); + +        ret = fd_ctx_get (fd, this, &tmp_pfd); +        if (ret < 0) { +                op_errno = -ret; +                gf_log (this->name, GF_LOG_ERROR, +			"pfd is NULL from fd=%p", fd); +                goto out; +        } +	pfd = (struct posix_fd *)(long)tmp_pfd; +        _fd = pfd->fd; + +        trav = dict->members_list; + +        while (trav) { +                ret = fhandle_pair (this, _fd, trav, flags); +                if (ret < 0) { +                        op_errno = -ret; +                        goto out; +                } +                trav = trav->next; +        } + +        op_ret = 0; + + out: +        SET_TO_OLD_FS_ID (); +        frame->root->rsp_refs = NULL; + +        STACK_UNWIND (frame, op_ret, op_errno); + +        return 0; +} + +  int32_t  posix_removexattr (call_frame_t *frame, xlator_t *this,                     loc_t *loc, const char *name) @@ -3739,7 +3960,9 @@ struct xlator_fops fops = {          .flush       = posix_flush,          .fsync       = posix_fsync,          .setxattr    = posix_setxattr, +        .fsetxattr   = posix_fsetxattr,          .getxattr    = posix_getxattr, +        .fgetxattr   = posix_fgetxattr,          .removexattr = posix_removexattr,          .fsyncdir    = posix_fsyncdir,          .access      = posix_access,  | 
